Page cover

Flag


FlagEnum 的用法大致相同,但它是 Enum 的 Subclass,且 Flag members 支援 bitwise operators & (AND)、| (OR)、^ (XOR) 和 ~ (INVERT); 這些結果值是 enumeration members。

PYTHON
import enum

class Permission(enum.Flag):
    READ = enum.auto()
    WRITE = enum.auto()
    EXECUTE = enum.auto()
    W=enum.auto()

# Individual permissions
print(Permission.READ.value)     # Output: 1
print(Permission.WRITE.value)    # Output: 2
print(Permission.EXECUTE.value)  # Output: 4

# Combined permissions
read_write = Permission.READ | Permission.WRITE
print(read_write)                     # Output: Permission.READ|WRITE

# Checking if a certain permission is in the combination
print(Permission.READ in read_write)  # Output: True
print(type(read_write))               # <flag 'Permission'>

IntFlag


IntFlagFlag 的用法大致相同,但它是 Flag 的 Subclass ,且 enumeration 值是 str 的實例。

IntFlag 更進一步,使 enumeration members 的行為更像整數。IntFlag members ,可以參與所有 int 的 operations。如果對 IntFlag members 執行任何整數運算,則結果值將失去 enumeration 狀態。

IntFlagEnum 之間的另一個重要區別是,如果沒有設置 Flag(值會為0),則 bool() 評估為 False

Flag 命名組合


命名組合被視為別名。別名在 iteration 期間不會顯示,但可以使用值查找。 IntFlag members 也是 int 的 Subclass,所以可以與 int 組合。

Flag boundary 參數


控制 Flag 及其 Subclasses 中如何處理超出範圍的值。

KEEP:超出範圍的值將被保留,並且 Flag membership 將被保留。這是 IntFlag 的預設值。 EJECT: 超出範圍的值將失去其 Flag membership ,並恢復為 intCONFORM: 超出範圍的值已將刪除無效值,留下有效的 Flag 值: STRICT: 超出範圍的值會導致引發 ValueError。這是 Flag 的預設值。

auto()


auto 可以用來代替 Enum 的值,其值是 auto 的實例。 是一個為 Enum members 生成值的 Class。目的是簡化 enumerations 的創建,其中 members 的確切值並不重要,從而使開發人員能夠專注於程式碼中更有意義的部分。

使用 auto 時,將調用 Enum 的 _generate_next_value_() 來獲取適當的值。

  • 對於 EnumIntEnum,Enum 的值將是最後一個值加 1。

  • 對於 FlagIntFlag ,Enum 的值將是第一個大於最高值的 2 的冪 (次方)。

  • 對於 StrEnum ,Enum 的值將是 member’s name 的小寫版本。

如果將 auto() 與手動指定的 Enum 值混合使用時,必須小心。

範例 – auto()


__generate_next_value__


您可以重寫 enumeration classes 中的 _generate_next_value_ 方法來更改 auto() 為 members 賦值的方式。 當您想要使用 auto() ,但需要對分配的值進行更多控制時,這非常有用。

參數
說明

name

正在定義的 member's name。

start

Enum 起始值。

count

當前已經定義的 members 數量。

last_values

以前值的 List。

object()


object() 是 Python 中的一個 built-in 函數,它返回一個新的無特徵物件。 object 是所有 Class 的基礎,它包含所有 Class 預設的 built-in 屬性和方法。

當您希望每個 enum member 都具有真正唯一且明確的值時,這可能很有用。例如:避免某些類型的錯誤,尤其是在具有許多 enum 類型的大型程序中。

然而,使用 object() 實例作為 enum 值也有一些缺點。 例如:這些值不是人類可讀的,並且無法序列化為 JSON 或其他格式。 它還可能使 debugging 變得更加困難,因為這些值不提供有關它們所代表的內容的任何訊息。 因此,請謹慎使用此功能,並考慮您的具體情況是否利大於弊。

在此範例中,Unique enum 具有三個 members,每個 member 的值都是唯一的 object() 實例。 當你運行這個程序時,

確切的輸出會有所不同,因為 object() 實例會被輸出為 <object at 0x...>,其中...是物件的 memory 地址。

@unique, @verify()


@unique 確保 enum class 中的所有 enumeration 值都是唯一的 (獨立的); 如果有任何重複,它將引發 ValueError 。

verify() decorator 用於確保各種限制條件; 失敗的限制條件會導致 ValueError。

UNIQUE: 確保每個值只有唯一的 enum member。 CONTINUOUS: 確保最低值的 member 和最高值的 member 之間不存在缺失值。 NAMED_FLAGS: 確保任何 flag 包含已經命名的 flags。當 flag 的值由 auto() 生成時,忽略檢查該 flag。

CONTINUOUSNAMED_FLAGS 僅支援整數的值。

show_flag_values()


show_flag_values(value) 返回 flag 值中包含的所有二次冪整數的列表。

__init__


__init__() 用於在創建 Class 的實例後對其進行初始化。 在 Enum 的 context 中,__init__() 方法可用於為 enum 的每個 member 執行附加設置。

範例 1:為 enum members 分配附加屬性,每個 member 都有一個名稱和一個縮寫。

重寫 __init__() 來為 enum 的每個 member 提供額外的設置。__init__() 不返回任何內容; 相反,它直接修改實例。 如果您嘗試從 __init__() 返回除 None 之外的任何內容,您將得到一個 TypeError

__init__() 的參數必須與定義 enum members 時提供的值匹配。 在 State Class 中,每個 enum member 都使用兩個 Tuple Strings 定義,這兩個 Strings 與 __init__()abbreviationcapital 參數匹配。

請注意,在定義 enum member 後對其進行修改,通常被認為是不好的做法,因為 enums 是 immutable (不可變的)。

範例 – __init__


Enum member 的值存儲在 .value 屬性中,但可以使用 __init__() 向 enum members 加入其他屬性。 這些附加屬性的訪問方式就像 Python 物件的任何其他屬性一樣。

Functional API


Enum 函數 API 允許您創建 enumeration 類型,這些類型基本上是一組值的符號名稱。

參數
說明

value

新 enumeration 的名稱。

names

enum members。這可以是 String、mapping、 names iterator 或 (name, value) pairs iterator。 這也可以是空格或逗號分隔的 String(除非另有說明,值將從 1 開始)

module

用作 enum 的 __module__ 屬性。對於 pickling 和 introspection 很有用。

qualname

用作 enum 的 __qualname__ 屬性。對於 introspection 很有用。

type

用作 Mixed-in Class。即,它定義 enumeration 的特定行為。 如果您希望 enum members 表現得像整數、Strings 等,這會很有用。

start

定義 enum members 自動編號的起始編號。

Enum 函數式 API 靈活且用途廣泛,使您能夠創建具有不同行為的複雜 enumeration 類型。

Last updated

Was this helpful?