enum
--- 對列舉的支援¶
在 3.4 版被加入.
原始碼:Lib/enum.py
列舉:
是一組綁定唯一值的代表名稱(成員)
可以用疊代的方式以定義的順序回傳其正式 (canonical)(即非別名)成員
使用 call 語法來透過值回傳成員
使用 index 語法來透過名稱回傳成員
列舉透過 class
語法或函式呼叫的語法來建立:
>>> from enum import Enum
>>> # class syntax
>>> class Color(Enum):
... RED = 1
... GREEN = 2
... BLUE = 3
>>> # functional syntax
>>> Color = Enum('Color', [('RED', 1), ('GREEN', 2), ('BLUE', 3)])
雖然我們可以用 class
語法來建立列舉,列舉並不是標準的 Python 類別。參考列舉有何差異以取得更多細節。
備註
命名方式
Color
類別是一個列舉(或 enum)Color.RED
、Color.GREEN
等屬性是列舉成員(或成員),並且使用上可以看作常數。列舉成員有名稱和值(
Color.RED
的名稱是RED
,Color.BLUE
的值是3
諸如此類)
模組內容¶
Enum 及其子類別的
type
。用來建立列舉常數的基礎類別。
用來建立列舉常數的基礎類別,可以使用位元操作來結合成員且其結果不失去
Flag
的成員資格。一個有
CONTINUOUS
、NAMED_FLAGS
及UNIQUE
這些值的列舉,和verify()
一起使用來確保給定的列舉符合多種限制。一個有
STRICT
、CONFORM
、EJECT
及KEEP
這些值的列舉,允許列舉對如何處理非法值做更細微的控制。列舉成員的實例會被取代成合適的值。
StrEnum
預設是小寫版本的成員名稱,其它列舉則預設是 1 且往後遞增。允許
Enum
成員擁有屬性且不會與成員名稱有衝突。value
及name
屬性是用這個方式來實作。Enum 類別的裝飾器,用來確保任何值只有綁定到一個名稱上。
Enum 類別的裝飾器,用來檢查列舉上使用者所選的限制。
讓
obj
變成成員。可以當作裝飾器使用。不讓
obj
變成成員。可以當作裝飾器使用。回傳旗標 (flag) 裡包含的所有 2 的次方的整數串列。
在 3.6 版被加入: Flag
, IntFlag
, auto
在 3.11 版被加入: StrEnum
, EnumCheck
, ReprEnum
, FlagBoundary
, property
, member
, nonmember
, global_enum
, show_flag_values
資料型別¶
- class enum.EnumType¶
EnumType 是列舉的 metaclass。EnumType 可以有子類別 -- 細節請參考 建立 EnumType 的子類別。
EnumType
is responsible for setting the correct__repr__()
,__str__()
,__format__()
, and__reduce__()
methods on the final enum, as well as creating the enum members, properly handling duplicates, providing iteration over the enum class, etc.- __call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)¶
這個方法可以用兩種不同的方式呼叫:
查詢已存在的成員:
- cls:
所呼叫的列舉類別。
- value:
要查詢的值。
使用
cls
列舉來建立新列舉(只有在現有列舉沒有任何成員時)
- __contains__(cls, member)¶
如果 member 屬於
cls
則回傳True
:>>> some_var = Color.RED >>> some_var in Color True >>> Color.RED.value in Color True
在 3.12 版的變更: 在 Python 3.12 之前,如果用非列舉成員做屬於檢查 (containment check) 會引發
TypeError
。- __dir__(cls)¶
回傳
['__class__', '__doc__', '__members__', '__module__']
及 cls 的成員名稱:>>> dir(Color) ['BLUE', 'GREEN', 'RED', '__class__', '__contains__', '__doc__', '__getitem__', '__init_subclass__', '__iter__', '__len__', '__members__', '__module__', '__name__', '__qualname__']
- __iter__(cls)¶
以定義的順序回傳在 cls 中的每個成員:
>>> list(Color) [<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 3>]
- __len__(cls)¶
回傳 cls 的成員數量:
>>> len(Color) 3
- __members__¶
回傳每個列舉名稱到其成員的對映,包括別名
- __reversed__(cls)¶
以跟定義相反的順序回傳 cls 的每個成員:
>>> list(reversed(Color)) [<Color.BLUE: 3>, <Color.GREEN: 2>, <Color.RED: 1>]
- _add_alias_()¶
Adds a new name as an alias to an existing member. Raises a
NameError
if the name is already assigned to a different member.
- _add_value_alias_()¶
Adds a new value as an alias to an existing member. Raises a
ValueError
if the value is already linked with a different member.
在 3.11 版被加入: Before 3.11
EnumType
was calledEnumMeta
, which is still available as an alias.
- class enum.Enum¶
Enum 是所有 enum 列舉的基礎類別。
- name¶
用來定義
Enum
成員的名稱:>>> Color.BLUE.name 'BLUE'
- value¶
Enum
成員給定的值:>>> Color.RED.value 1
成員的值,可以在
__new__()
設定。備註
列舉成員的值
成員的值可以是任何值:
int
、str
等等。如果實際使用什麼值並不重要,你可以使用auto
實例,它會為你選擇合適的值。更多細節請參考auto
。While mutable/unhashable values, such as
dict
,list
or a mutabledataclass
, can be used, they will have a quadratic performance impact during creation relative to the total number of mutable/unhashable values in the enum.
- _name_¶
成員名稱。
- _order_¶
已不再使用,只為了向後相容而保留(類別屬性,在類別建立時移除)
- _ignore_¶
_ignore_
只有在建立的時候用到,在列舉建立完成後會被移除。_ignore_
是一個不會變成成員的名稱串列,在列舉建立完成後其名稱會被移除。範例請參考 TimePeriod。
- __dir__(self)¶
回傳
['__class__', '__doc__', '__module__', 'name', 'value']
及任何 self.__class__ 上定義的公開方法:>>> from datetime import date >>> class Weekday(Enum): ... MONDAY = 1 ... TUESDAY = 2 ... WEDNESDAY = 3 ... THURSDAY = 4 ... FRIDAY = 5 ... SATURDAY = 6 ... SUNDAY = 7 ... @classmethod ... def today(cls): ... print('today is %s' % cls(date.today().isoweekday()).name) ... >>> dir(Weekday.SATURDAY) ['__class__', '__doc__', '__eq__', '__hash__', '__module__', 'name', 'today', 'value']
- _generate_next_value_(name, start, count, last_values)¶
- name:
定義的成員名稱(例如 'RED')。
- start:
列舉的開始值,預設為 1。
- count:
已定義的成員數量,不包含目前這一個。
- last_values:
一個之前值的串列。
一個 staticmethod,用來決定
auto
下一個要回傳的值的:>>> from enum import auto >>> class PowersOfThree(Enum): ... @staticmethod ... def _generate_next_value_(name, start, count, last_values): ... return 3 ** (count + 1) ... FIRST = auto() ... SECOND = auto() ... >>> PowersOfThree.SECOND.value 9
- __init__(self, *args, **kwds)¶
預設情況下,不執行任何操作。如果在成員賦值中給出多個值,這些值將成為與
__init__
分別的引數;例如>>> from enum import Enum >>> class Weekday(Enum): ... MONDAY = 1, 'Mon'
Weekday.__init__()
將被稱為Weekday.__init__(self, 1, 'Mon')
- __init_subclass__(cls, **kwds)¶
一個 classmethod,用來進一步設定後續的子類別,預設不做任何事。
- _missing_(cls, value)¶
一個 classmethod,用來查詢在 cls 裡找不到的值。預設不做任何事,但可以被覆寫以實作客製化的搜尋行為:
>>> from enum import StrEnum >>> class Build(StrEnum): ... DEBUG = auto() ... OPTIMIZED = auto() ... @classmethod ... def _missing_(cls, value): ... value = value.lower() ... for member in cls: ... if member.value == value: ... return member ... return None ... >>> Build.DEBUG.value 'debug' >>> Build('deBUG') <Build.DEBUG: 'debug'>
- __new__(cls, *args, **kwds)¶
預設情況下不存在。如果有指定,無論是在列舉類別定義中還是在 mixin 類別中(例如
int
),都將傳遞成員賦值中給出的所有值;例如>>> from enum import Enum >>> class MyIntEnum(int, Enum): ... TWENTYSIX = '1a', 16
results in the call
int('1a', 16)
and a value of26
for the member.備註
當寫自訂的
__new__
時,不要使用super().__new__
,而是要呼叫適當的__new__
。
- __repr__(self)¶
回傳呼叫 repr() 時使用的字串。預設回傳 Enum 名稱、成員名稱及值,但可以被覆寫:
>>> class OtherStyle(Enum): ... ALTERNATE = auto() ... OTHER = auto() ... SOMETHING_ELSE = auto() ... def __repr__(self): ... cls_name = self.__class__.__name__ ... return f'{cls_name}.{self.name}' ... >>> OtherStyle.ALTERNATE, str(OtherStyle.ALTERNATE), f"{OtherStyle.ALTERNATE}" (OtherStyle.ALTERNATE, 'OtherStyle.ALTERNATE', 'OtherStyle.ALTERNATE')
- __str__(self)¶
回傳呼叫 str() 時使用的字串。預設回傳 Enum 名稱及成員名稱,但可以被覆寫:
>>> class OtherStyle(Enum): ... ALTERNATE = auto() ... OTHER = auto() ... SOMETHING_ELSE = auto() ... def __str__(self): ... return f'{self.name}' ... >>> OtherStyle.ALTERNATE, str(OtherStyle.ALTERNATE), f"{OtherStyle.ALTERNATE}" (<OtherStyle.ALTERNATE: 1>, 'ALTERNATE', 'ALTERNATE')
- __format__(self)¶
回傳呼叫 format() 及 f-string 時使用的字串。預設回傳
__str__()
的回傳值,但可以被覆寫:>>> class OtherStyle(Enum): ... ALTERNATE = auto() ... OTHER = auto() ... SOMETHING_ELSE = auto() ... def __format__(self, spec): ... return f'{self.name}' ... >>> OtherStyle.ALTERNATE, str(OtherStyle.ALTERNATE), f"{OtherStyle.ALTERNATE}" (<OtherStyle.ALTERNATE: 1>, 'OtherStyle.ALTERNATE', 'ALTERNATE')
在 3.12 版的變更: 新增 Dataclass support
- class enum.IntEnum¶
IntEnum is the same as
Enum
, but its members are also integers and can be used anywhere that an integer can be used. If any integer operation is performed with an IntEnum member, the resulting value loses its enumeration status.>>> from enum import IntEnum >>> class Number(IntEnum): ... ONE = 1 ... TWO = 2 ... THREE = 3 ... >>> Number.THREE <Number.THREE: 3> >>> Number.ONE + Number.TWO 3 >>> Number.THREE + 5 8 >>> Number.THREE == 3 True
在 3.11 版的變更: 為了更好地支援現存常數取代 (replacement of existing constants) 的使用情境,
__str__()
現在會是int.__str__()
。為了同樣的理由,__format__()
已經是int.__format__()
。
- class enum.StrEnum¶
StrEnum
is the same asEnum
, but its members are also strings and can be used in most of the same places that a string can be used. The result of any string operation performed on or with a StrEnum member is not part of the enumeration.備註
stdlib 裡有些地方會檢查只能是
str
而不是str
的子類別(也就是type(unknown) == str
而不是isinstance(unknown, str)
),在這些地方你需要使用str(StrEnum.member)
。備註
為了更好地支援現存常數取代 (replacement of existing constants) 的使用情境,
__str__()
現在會是str.__str__()
。為了同樣的理由,__format__()
也會是str.__format__()
。在 3.11 版被加入.
- class enum.Flag¶
Flag
與Enum
相同,但其成員支援位元運算子&
(AND)、|
(OR)、^
(XOR) 和~
(INVERT);這些操作的結果是列舉的成員(的別名)。- __contains__(self, value)¶
如果 value 在 self 裡則回傳 True:
>>> from enum import Flag, auto >>> class Color(Flag): ... RED = auto() ... GREEN = auto() ... BLUE = auto() ... >>> purple = Color.RED | Color.BLUE >>> white = Color.RED | Color.GREEN | Color.BLUE >>> Color.GREEN in purple False >>> Color.GREEN in white True >>> purple in white True >>> white in purple False
- __iter__(self):
回傳所有包含的非別名成員:
>>> list(Color.RED) [<Color.RED: 1>] >>> list(purple) [<Color.RED: 1>, <Color.BLUE: 4>]
在 3.11 版被加入.
- __len__(self):
回傳旗標裡的成員數量:
>>> len(Color.GREEN) 1 >>> len(white) 3
在 3.11 版被加入.
- __bool__(self):
如果成員在旗標裡則回傳 True,否則回傳 False:
>>> bool(Color.GREEN) True >>> bool(white) True >>> black = Color(0) >>> bool(black) False
- __or__(self, other)¶
回傳和 other 做 OR 過後的二進位旗標:
>>> Color.RED | Color.GREEN <Color.RED|GREEN: 3>
- __and__(self, other)¶
回傳和 other 做 AND 過後的二進位旗標:
>>> purple & white <Color.RED|BLUE: 5> >>> purple & Color.GREEN <Color: 0>
- __xor__(self, other)¶
回傳和 other 做 XOR 過後的二進位旗標:
>>> purple ^ white <Color.GREEN: 2> >>> purple ^ Color.GREEN <Color.RED|GREEN|BLUE: 7>
- __invert__(self):
Returns all the flags in type(self) that are not in self:
>>> ~white <Color: 0> >>> ~purple <Color.GREEN: 2> >>> ~Color.RED <Color.GREEN|BLUE: 6>
在 3.11 版的變更: 值為 0 的旗標的 repr() 已改變。現在是:
>>> Color(0) <Color: 0>
- class enum.IntFlag¶
IntFlag
is the same asFlag
, but its members are also integers and can be used anywhere that an integer can be used.>>> from enum import IntFlag, auto >>> class Color(IntFlag): ... RED = auto() ... GREEN = auto() ... BLUE = auto() ... >>> Color.RED & 2 <Color: 0> >>> Color.RED | 2 <Color.RED|GREEN: 3>
如果 IntFlag 成員經過任何整數運算,其結果不是 IntFlag:
>>> Color.RED + 2 3
If a
Flag
operation is performed with an IntFlag member and:結果是合法的 IntFlag:回傳 IntFlag
the result is not a valid IntFlag: the result depends on the
FlagBoundary
setting
The
repr()
of unnamed zero-valued flags has changed. It is now:>>> Color(0) <Color: 0>
在 3.11 版的變更: 為了更好地支援現存常數取代 (replacement of existing constants) 的使用情境,
__str__()
現在會是int.__str__()
。為了同樣的理由,__format__()
已經是int.__format__()
。IntFlag
的反轉 (inversion) 現在會回傳正值,該值是不在給定旗標的所有旗標聯集,而不是一個負值。這符合現有Flag
的行為。
- class enum.ReprEnum¶
ReprEnum
使用Enum
的repr()
,但使用混合資料類型的str()
:繼承
ReprEnum
來保留混合資料類型的str()
/format()
,而不是使用Enum
預設的str()
。在 3.11 版被加入.
- class enum.EnumCheck¶
EnumCheck 包含
verify()
裝飾器使用的選項,以確保多樣的限制,不符合限制會產生ValueError
。- UNIQUE¶
確保每個值只有一個名稱:
>>> from enum import Enum, verify, UNIQUE >>> @verify(UNIQUE) ... class Color(Enum): ... RED = 1 ... GREEN = 2 ... BLUE = 3 ... CRIMSON = 1 Traceback (most recent call last): ... ValueError: aliases found in <enum 'Color'>: CRIMSON -> RED
- CONTINUOUS¶
確保在最小值成員跟最大值成員間沒有缺少值:
>>> from enum import Enum, verify, CONTINUOUS >>> @verify(CONTINUOUS) ... class Color(Enum): ... RED = 1 ... GREEN = 2 ... BLUE = 5 Traceback (most recent call last): ... ValueError: invalid enum 'Color': missing values 3, 4
- NAMED_FLAGS¶
確保任何旗標群組 / 遮罩只包含命名旗標 -- 當值是用指定而不是透過
auto()
產生時是很實用的:>>> from enum import Flag, verify, NAMED_FLAGS >>> @verify(NAMED_FLAGS) ... class Color(Flag): ... RED = 1 ... GREEN = 2 ... BLUE = 4 ... WHITE = 15 ... NEON = 31 Traceback (most recent call last): ... ValueError: invalid Flag 'Color': aliases WHITE and NEON are missing combined values of 0x18 [use enum.show_flag_values(value) for details]
備註
CONTINUOUS 和 NAMED_FLAGS 是設計用來運作在整數值的成員上。
在 3.11 版被加入.
- class enum.FlagBoundary¶
FlagBoundary
controls how out-of-range values are handled inFlag
and its subclasses.- STRICT¶
範圍外的值會引發
ValueError
。這是Flag
的預設行為:>>> from enum import Flag, STRICT, auto >>> class StrictFlag(Flag, boundary=STRICT): ... RED = auto() ... GREEN = auto() ... BLUE = auto() ... >>> StrictFlag(2**2 + 2**4) Traceback (most recent call last): ... ValueError: <flag 'StrictFlag'> invalid value 20 given 0b0 10100 allowed 0b0 00111
- CONFORM¶
Out-of-range values have invalid values removed, leaving a valid
Flag
value:>>> from enum import Flag, CONFORM, auto >>> class ConformFlag(Flag, boundary=CONFORM): ... RED = auto() ... GREEN = auto() ... BLUE = auto() ... >>> ConformFlag(2**2 + 2**4) <ConformFlag.BLUE: 4>
在 3.11 版被加入.
支援 __dunder__
名稱¶
__members__
是一個唯讀有序的成員名稱
:成員
項目的對映。只有在類別上可用。
__new__()
, if specified, must create and return the enum members;
it is also a very good idea to set the member's _value_
appropriately.
Once all the members are created it is no longer used.
支援 _sunder_
名稱¶
_add_alias_()
-- adds a new name as an alias to an existing member._add_value_alias_()
-- adds a new value as an alias to an existing member._name_
-- 成員名稱_value_
-- 成員的值;可以在__new__
設定_missing_()
-- 當值沒有被找到時會使用的查詢函式;可以被覆寫_order_
-- 不再被使用,僅為了向後相容而保留(類別屬性,在類別建立時移除)_generate_next_value_()
-- 用來為列舉成員取得合適的值;可以被覆寫While
_sunder_
names are generally reserved for the further development of theEnum
class and can not be used, some are explicitly allowed:_repr_*
(e.g._repr_html_
), as used in IPython's rich display
在 3.6 版被加入: _missing_
、_order_
、_generate_next_value_
在 3.7 版被加入: _ignore_
在 3.13 版被加入: _add_alias_
, _add_value_alias_
, _repr_*
通用項目與裝飾器¶
- class enum.auto¶
auto can be used in place of a value. If used, the Enum machinery will call an
Enum
's_generate_next_value_()
to get an appropriate value. ForEnum
andIntEnum
that appropriate value will be the last value plus one; forFlag
andIntFlag
it will be the first power-of-two greater than the highest value; forStrEnum
it will be the lower-cased version of the member's name. Care must be taken if mixing auto() with manually specified values.auto 實例只有在最上層的賦值時才會被解析:
FIRST = auto()
可以運作(auto() 會被取代成1
)SECOND = auto(), -2
可以運作(auto 會被取代成2
, 因此2, -2
會被用來建立列舉成員SECOND
;THREE = [auto(), -3]
無法運作(<auto 實例>, -3
會被用來建立列舉成員THREE
)
在 3.11.1 版的變更: 在之前的版本中,
auto()
必須是賦值行裡的唯一內容才能運作正確。可以覆寫
_generate_next_value_
來客製 auto 使用的值。備註
在 3.13 預設
_generate_next_value_
總是回傳最大的成員值加一,如果任何成員是不相容的類型就會失敗。
- @enum.property¶
和內建的 property 相似的裝飾器,但只專門針對列舉。它允許成員屬性和成員本身有相同名稱。
備註
屬性和成員必須定義在分開的類別裡;例如 value 和 name 屬性定義在 Enum 類別而 Enum 子類別可以定義成員名稱為
value
和name
。在 3.11 版被加入.
- @enum.unique¶
專門針對列舉的
class
裝飾器。它搜尋列舉的__members__
,蒐集任何它找到的別名;如果有找到任何別名則引發ValueError
並附上細節:>>> from enum import Enum, unique >>> @unique ... class Mistake(Enum): ... ONE = 1 ... TWO = 2 ... THREE = 3 ... FOUR = 3 ... Traceback (most recent call last): ... ValueError: duplicate values found in <enum 'Mistake'>: FOUR -> THREE
- @enum.member¶
列舉所使用的裝飾器:其目標會變成成員。
在 3.11 版被加入.
- @enum.nonmember¶
列舉所使用的裝飾器:其目標不會變成成員。
在 3.11 版被加入.
- @enum.global_enum¶
修改列舉的
str()
及repr()
的裝飾器,讓成員顯示為屬於模組而不是其類別。應該只有當列舉成員被匯出到模組的全域命名空間才使用(範例請參考re.RegexFlag
)。在 3.11 版被加入.
- enum.show_flag_values(value)¶
回傳在旗標值中包含的所有 2 的次方的整數串列。
在 3.11 版被加入.
備註¶
這三種列舉類型是設計來直接取代現有以整數及字串為基底的值;因此它們有額外的限制:
__str__
使用值而不是列舉成員的名稱
__format__
因為使用__str__
,也會使用值而不是列舉成員的名稱如果你不需要或不想要這些限制,你可以透過混合
int
或str
類型來建立自己的基礎類別:>>> from enum import Enum >>> class MyIntEnum(int, Enum): ... pass或者你也可以在你的列舉重新給定合適的
str()
:>>> from enum import Enum, IntEnum >>> class MyIntEnum(IntEnum): ... __str__ = Enum.__str__