自定義 IntFlag members 時要小心,以避免意外地將組合定義為單個權限。或是直接使用 auto 定義 members。
例如:為 member 分配 3 的權限,將意味著它同時包含 1 和 2 的權限。
PYTHON
import enumclassPermission(enum.IntFlag): NONE =0 READ =1 WRITE =2 EXECUTE =4 ALL =7# Individual permissionsprint(Permission.READ)# Output: 1# Combined permissionsread_write = Permission.READ | Permission.WRITEprint(read_write)# Output: 3print(type(read_write))# Output: <flag 'Permission'> # Checking if a certain permission is in the combinationprint(Permission.READ in read_write)# Output: True# Compare with integersprint(Permission.ALL ==7)# Output: Trueprint(Permission.ALL & Permission.NONE)# Output: 0print(bool(Permission.ALL & Permission.NONE))# Output: False
Flag 命名組合
命名組合被視為別名。別名在 iteration 期間不會顯示,但可以使用值查找。 IntFlag members 也是 int 的 Subclass,所以可以與 int 組合。
PYTHON
from enum import IntFlagclassPerm(IntFlag): R =4 W =2 X =1print(Perm.R | Perm.W)# Output: 6print(Perm.R + Perm.W)# Output: 6RW = Perm.R | Perm.Wprint(Perm.R in RW)# Output: True
Flag boundary 參數
控制 Flag 及其 Subclasses 中如何處理超出範圍的值。
KEEP:超出範圍的值將被保留,並且 Flag membership 將被保留。這是 IntFlag 的預設值。 EJECT: 超出範圍的值將失去其 Flag membership ,並恢復為 int。 CONFORM: 超出範圍的值已將刪除無效值,留下有效的 Flag 值: STRICT: 超出範圍的值會導致引發 ValueError。這是 Flag 的預設值。
PYTHON
import enumclassKeepFlag(enum.Flag,boundary=enum.KEEP): RED = enum.auto() GREEN = enum.auto() BLUE = enum.auto()print(KeepFlag(2**2))# Output: KeepFlag.BLUEprint(KeepFlag(2**2+2**4))# Output: KeepFlag.BLUE|16print(KeepFlag.RED.value)# Output: 1print(KeepFlag.GREEN.value)# Output: 2print(KeepFlag.BLUE.value)# Output: 4# =========================================================classKeepFlag(enum.Flag,boundary=enum.EJECT): RED = enum.auto() GREEN = enum.auto() BLUE = enum.auto()print(KeepFlag(2**2+2**4))# Output: 20# =========================================================classKeepFlag(enum.Flag,boundary=enum.CONFORM): RED = enum.auto() GREEN = enum.auto() BLUE = enum.auto()print(KeepFlag(2**2+2**4))# Output: KeepFlag.BLUE# =========================================================classKeepFlag(enum.Flag,boundary=enum.STRICT): RED = enum.auto() GREEN = enum.auto() BLUE = enum.auto()print(KeepFlag(2**2+2**4))'''Output: ValueError: <flag 'KeepFlag'> invalid value 20 given 0b0 10100 allowed 0b0 00111'''
auto()
auto 可以用來代替 Enum 的值,其值是 auto 的實例。 是一個為 Enum members 生成值的 Class。目的是簡化 enumerations 的創建,其中 members 的確切值並不重要,從而使開發人員能夠專注於程式碼中更有意義的部分。
使用 auto 時,將調用 Enum 的 _generate_next_value_() 來獲取適當的值。
在此範例中,Unique enum 具有三個 members,每個 member 的值都是唯一的 object() 實例。 當你運行這個程序時,
PYTHON
from enum import EnumclassUnique(Enum): FIRST =object() SECOND =object() THIRD =object()print(Unique.FIRST.value)# Output: <object object at 0x000002CE0C8D4260>print(Unique.SECOND.value)# Output: <object object at 0x000002CE0C8D4260>print(Unique.THIRD.value)# Output: <object object at 0x000002CE0C8D4270>print(Unique.FIRST.value == Unique.SECOND.value)# Output: False
確切的輸出會有所不同,因為 object() 實例會被輸出為 <object at 0x...>,其中...是物件的 memory 地址。
import enum@enum.uniqueclassColor(enum.Enum): RED =1 GREEN =2 BLUE =2defdescribe(self):# this is a member functionreturnf"This is a color with value {self.value}"@classmethoddeffavorite_color(cls):return cls.GREEN# Usage:print(Color.RED)# Output: Color.REDprint(Color.RED.value)# Output: 1print(Color.RED.describe())# Output: This is a color with value 1print(Color.favorite_color())# Output: Color.GREEN'''Output: ValueError: duplicate values found in <enum 'Color'>: BLUE -> GREEN'''
UNIQUE: 確保每個值只有唯一的 enum member。 CONTINUOUS: 確保最低值的 member 和最高值的 member 之間不存在缺失值。 NAMED_FLAGS: 確保任何 flag 包含已經命名的 flags。當 flag 的值由 auto() 生成時,忽略檢查該 flag。
CONTINUOUS,NAMED_FLAGS 僅支援整數的值。
PYTHON
import enum@enum.verify(enum.UNIQUE)classColor(enum.Enum): RED =1 GREEN =2 BLUE =3 CRIMSON =1# Output:# ValueError: aliases found in <enum 'Color'>: CRIMSON -> RED@enum.verify(enum.CONTINUOUS)classColor(enum.Enum): RED =1 GREEN =2 BLUE =5# Output:# ValueError: invalid enum 'Color': missing values 3, 4@enum.verify(enum.NAMED_FLAGS)classColor(enum.Flag): RED =1 GREEN =2 BLUE =4 WHITE =15 NEON =31# ValueError: invalid Flag 'Color': aliases WHITE and NEON are missing combined values of 0x18 # [use enum.show_flag_values(value) for details]print(enum.show_flag_values(15))# Output: [1, 2, 4, 8]print(enum.show_flag_values(31))# Output: [1, 2, 4, 8, 16]
show_flag_values()
show_flag_values(value) 返回 flag 值中包含的所有二次冪整數的列表。
PYTHON
import enumclassColor(enum.Flag): RED =1 GREEN =2 BLUE =4 WHITE =15 NEON =31print(enum.show_flag_values(15))# Output: [1, 2, 4, 8]print(enum.show_flag_values(31))# Output: [1, 2, 4, 8, 16]
__init__
__init__() 用於在創建 Class 的實例後對其進行初始化。 在 Enum 的 context 中,__init__() 方法可用於為 enum 的每個 member 執行附加設置。