
Flag
Flag 與 Enum 的用法大致相同,但它是 Enum 的 Subclass,且 Flag members 支援 bitwise operators & (AND)、| (OR)、^ (XOR) 和 ~ (INVERT); 這些結果值是 enumeration members。
Enum 適合 enumeration members 更加互斥的情況,即,它們不應該組合使用。
Flag 適合 enumeration members 想要組合的情況。 一個用例可以是管理一組使用者權限。
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
IntFlag 與 Flag 的用法大致相同,但它是 Flag 的 Subclass ,且 enumeration 值是 str 的實例。
IntFlag 更進一步,使 enumeration members 的行為更像整數。IntFlag members ,可以參與所有 int 的 operations。如果對 IntFlag members 執行任何整數運算,則結果值將失去 enumeration 狀態。
IntFlag 和 Enum 之間的另一個重要區別是,如果沒有設置 Flag(值會為0),則 bool() 評估為 False。
自定義 IntFlag members 時要小心,以避免意外地將組合定義為單個權限。或是直接使用 auto 定義 members。
例如:為 member 分配 3 的權限,將意味著它同時包含 1 和 2 的權限。
Flag 命名組合
命名組合被視為別名。別名在 iteration 期間不會顯示,但可以使用值查找。 IntFlag members 也是 int 的 Subclass,所以可以與 int 組合。
Flag boundary 參數
控制 Flag 及其 Subclasses 中如何處理超出範圍的值。
KEEP:超出範圍的值將被保留,並且 Flag membership 將被保留。這是 IntFlag 的預設值。 EJECT: 超出範圍的值將失去其 Flag membership ,並恢復為 int。 CONFORM: 超出範圍的值已將刪除無效值,留下有效的 Flag 值: STRICT: 超出範圍的值會導致引發 ValueError。這是 Flag 的預設值。
auto()
auto 可以用來代替 Enum 的值,其值是 auto 的實例。 是一個為 Enum members 生成值的 Class。目的是簡化 enumerations 的創建,其中 members 的確切值並不重要,從而使開發人員能夠專注於程式碼中更有意義的部分。
使用 auto 時,將調用 Enum 的 _generate_next_value_() 來獲取適當的值。
對於
Enum和IntEnum,Enum 的值將是最後一個值加 1。對於
Flag和IntFlag,Enum 的值將是第一個大於最高值的 2 的冪 (次方)。對於
StrEnum,Enum 的值將是 member’s name 的小寫版本。
如果將 auto() 與手動指定的 Enum 值混合使用時,必須小心。
Python 3.11.1 更新。
3.11.1 之前: auto() 必須是賦值右側的唯一項。
3.11.1 開始:您可以以更靈活的方式使用 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() 實例。 當你運行這個程序時,
@unique, @verify()
@unique 確保 enum class 中的所有 enumeration 值都是唯一的 (獨立的); 如果有任何重複,它將引發 ValueError 。
verify() decorator 用於確保各種限制條件; 失敗的限制條件會導致 ValueError。
UNIQUE: 確保每個值只有唯一的 enum member。 CONTINUOUS: 確保最低值的 member 和最高值的 member 之間不存在缺失值。 NAMED_FLAGS: 確保任何 flag 包含已經命名的 flags。當 flag 的值由 auto() 生成時,忽略檢查該 flag。
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__() 的abbreviation 和 capital 參數匹配。
範例 – __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 自動編號的起始編號。
如果未提供 module,並且 Enum 無法確定它是什麼,則新的 Enum members 將不會 unpicklable; 為了使錯誤更接近 source,pickling 將被禁用。
Last updated
Was this helpful?