GeezerVison is showing python.github.io — enum --- 對列舉的支援 — Python 3.15.2 說明文件
enum --- 對列舉的支援¶
原始碼:Lib/enum.py
列舉:
列舉透過 class 語法或函式呼叫的語法來建立:
>>> from enum import Enum
>>> # class 語法
>>> class Color(Enum):
... RED = 1
... GREEN = 2
... BLUE = 3
>>> # 函式語法
>>> Color = Enum('Color', [('RED', 1), ('GREEN', 2), ('BLUE', 3)])
雖然我們可以用 class 語法來建立列舉,列舉並不是標準的 Python 類別。參考列舉有何差異以取得更多細節。
模組內容¶
在 3.6 版被加入: Flag, IntFlag, auto
在 3.11 版被加入: StrEnum, EnumCheck, ReprEnum, FlagBoundary, property, member, nonmember, global_enum, show_flag_values
資料型別¶
-
class enum.EnumType¶
EnumType 是 enum 列舉的 metaclass。EnumType 可以有子類別 -- 細節請參考 建立 EnumType 的子類別。
EnumType 負責在最後的列舉上面設定正確的 __repr__()、__str__()、__format__() 及 __reduce__() 方法,以及建立列舉成員、正確處理重複、提供列舉類別的疊代等等。
在 3.11 版被加入: 在 3.11 之前,EnumType 稱作 EnumMeta,其目前仍可作為別名使用。
-
__call__(cls, value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)¶
這個方法可以用兩種不同的方式呼叫:
-
__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__']
-
__getitem__(cls, name)¶
回傳 cls 中符合 name 的列舉成員,或引發 KeyError:
>>> Color['BLUE']
<Color.BLUE: 3>
-
__iter__(cls)¶
以定義的順序回傳在 cls 中的每個成員:
>>> list(Color)
[<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 3>]
-
__len__(cls)¶
回傳 cls 的成員數量:
-
__members__¶
回傳每個列舉名稱到其成員的對映,包括別名
-
__reversed__(cls)¶
以跟定義相反的順序回傳 cls 的每個成員:
>>> list(reversed(Color))
[<Color.BLUE: 3>, <Color.GREEN: 2>, <Color.RED: 1>]
-
class enum.Enum¶
Enum 是所有 enum 列舉的基礎類別。
-
name¶
用來定義 Enum 成員的名稱:
>>> Color.BLUE.name
'BLUE'
-
value¶
Enum 成員給定的值:
成員的值,可以在 __new__() 設定。
備註
列舉成員的值
成員的值可以是任何值:int、str 等等。如果實際使用什麼值並不重要,你可以使用 auto 實例,它會為你選擇合適的值。更多細節請參考 auto。
雖然可以使用可變的 (mutable) / 不可雜湊的 (unhashable) 值,例如 dict、list 或可變的 dataclass,它們在建立期間會對效能產生相對於列舉中可變的 / 不可雜湊的值總數量的二次方影響。
-
_name_¶
成員名稱。
-
_value_¶
成員的值,可以在 __new__() 設定。
-
_order_¶
已不再使用,只為了向後相容而保留(類別屬性,在類別建立時移除)
The _order_ attribute can be provided to help keep Python 2 / Python 3 code in sync.
It will be checked against the actual order of the enumeration and raise an error if the two do not match:
>>> class Color(Enum):
... _order_ = 'RED GREEN BLUE'
... RED = 1
... BLUE = 3
... GREEN = 2
...
Traceback (most recent call last):
...
TypeError: member order does not match _order_:
['RED', 'BLUE', 'GREEN']
['RED', 'GREEN', 'BLUE']
備註
In Python 2 code the _order_ attribute is necessary as definition
order is lost before it can be recorded.
-
_ignore_¶
_ignore_ 只有在建立的時候用到,在列舉建立完成後會被移除。
_ignore_ 是一個不會變成成員的名稱串列,在列舉建立完成後其名稱會被移除。範例請參考 TimePeriod。
-
__dir__(self)¶
回傳 ['__class__', '__doc__', '__module__', 'name', 'value'] 及任何 self.__class__ 上定義的公開方法:
>>> from enum import Enum
>>> import datetime as dt
>>> class Weekday(Enum):
... MONDAY = 1
... TUESDAY = 2
... WEDNESDAY = 3
... THURSDAY = 4
... FRIDAY = 5
... SATURDAY = 6
... SUNDAY = 7
... @classmethod
... def today(cls):
... print(f'today is {cls(dt.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 下一個要回傳的值。
備註
對標準的 Enum 類別來說,下一個被選擇的值是所看過的最大值加一。
對 Flag 類別來說,下一個被選擇的值是下一個最大的 2 的次方的數字。
This method may be overridden, e.g.:
>>> from enum import auto, Enum
>>> 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
在 3.13 版的變更: Prior versions would use the last seen value instead of the highest value.
-
__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 auto, 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
會產生呼叫 int('1a', 16) 而該成員的值為 26。
備註
當寫自訂的 __new__ 時,不要使用 super().__new__,而是要呼叫適當的 __new__。
-
__repr__(self)¶
回傳呼叫 repr() 時使用的字串。預設回傳 Enum 名稱、成員名稱及值,但可以被覆寫:
>>> from enum import auto, 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 名稱及成員名稱,但可以被覆寫:
>>> from enum import auto, 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__() 的回傳值,但可以被覆寫:
>>> from enum import auto, Enum
>>> 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')
-
_add_alias_()¶
新增一個名稱作為現有成員的別名:
>>> Color.RED._add_alias_("ERROR")
>>> Color.ERROR
<Color.RED: 1>
如果該名稱已經被指派給不同的成員,則會引發 NameError。
-
_add_value_alias_()¶
新增一個值作為現有成員的別名:
>>> Color.RED._add_value_alias_(42)
>>> Color(42)
<Color.RED: 1>
-
class enum.IntEnum¶
IntEnum 和 Enum 一樣,但其成員同時也是整數而可以被用在任何使用整數的地方。如果 IntEnum 成員經過任何整數運算,結果值會失去其列舉狀態。
>>> 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 和 Enum 一樣,但其成員同時也是字串而可以被用在幾乎所有使用字串的地方。StrEnum 成員經過任何字串操作的結果會不再是列舉的一部份。
>>> from enum import StrEnum, auto
>>> class Color(StrEnum):
... RED = 'r'
... GREEN = 'g'
... BLUE = 'b'
... UNKNOWN = auto()
...
>>> Color.RED
<Color.RED: 'r'>
>>> Color.UNKNOWN
<Color.UNKNOWN: 'unknown'>
>>> str(Color.UNKNOWN)
'unknown'
備註
stdlib 裡有些地方會檢查只能是 str 而不是 str 的子類別(也就是 type(unknown) == str 而不是 isinstance(unknown, str)),在這些地方你需要使用 str(MyStrEnum.MY_MEMBER)。
備註
為了更好地支援現存常數取代 (replacement of existing constants) 的使用情境,__str__() 現在會是 str.__str__()。為了同樣的理由,__format__() 也會是 str.__format__()。
-
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>]
-
__len__(self)¶
回傳旗標裡的成員數量:
>>> len(Color.GREEN)
1
>>> len(white)
3
-
__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)¶
回傳所有在 type(self) 但不在 self 裡的旗標:
>>> ~white
<Color: 0>
>>> ~purple
<Color.GREEN: 2>
>>> ~Color.RED
<Color.GREEN|BLUE: 6>
-
_numeric_repr_()¶
用來格式化任何剩下未命名數值的函式。預設是值的 repr,常見選擇是 hex() 和 oct()。
在 3.11 版的變更: 值為 0 的旗標的 repr() 已改變。現在是:
-
class enum.IntFlag¶
IntFlag 和 Flag 一樣,但其成員同時也是整數而可以被用在任何使用整數的地方。
>>> 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:
如果 IntFlag 成員經過 Flag 操作且:
未命名且值為 0 的旗標的 repr() 已改變。現在是:
在 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()。
-
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 是設計用來運作在整數值的成員上。
-
class enum.FlagBoundary¶
FlagBoundary 控制在 Flag 及其子類別中如何處理範圍外的值。
-
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¶
會移除範圍外的值中的非法值,留下合法的 Flag 值:
>>> 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>
-
EJECT¶
範圍外的值會失去它們的 Flag 成員資格且恢復成 int。
>>> from enum import Flag, EJECT, auto
>>> class EjectFlag(Flag, boundary=EJECT):
... RED = auto()
... GREEN = auto()
... BLUE = auto()
...
>>> EjectFlag(2**2 + 2**4)
20
-
KEEP¶
範圍外的值會被保留,Flag 成員資格也會被保留。這是 IntFlag 的預設行為:
>>> from enum import Flag, KEEP, auto
>>> class KeepFlag(Flag, boundary=KEEP):
... RED = auto()
... GREEN = auto()
... BLUE = auto()
...
>>> KeepFlag(2**2 + 2**4)
<KeepFlag.BLUE|16: 20>
-
class enum.EnumDict¶
EnumDict 是 dict 的子類別,用來作為定義列舉類別的命名空間(參見 Preparing the class namespace)。它被公開來使得 EnumType 的子類別能具有進階行為,例如讓每個成員有多個值。它應該在被呼叫時帶上正在建立的列舉類別名稱,否則私有名稱和內部類別將無法被正確處理。
注意只有 MutableMapping 介面(__setitem__() 和 update())被覆寫。可能可以使用其他 dict 操作來繞過檢查,例如 |=。
-
member_names¶
一個成員名稱的串列。
支援的 _sunder_ 名稱¶
在 3.6 版被加入: _missing_、_order_、_generate_next_value_
在 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.
For Enum and IntEnum that appropriate value will be the highest value seen
plus one; for Flag and IntFlag it will be the first power-of-two greater
than the highest value seen; for StrEnum 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;
THIRD = [auto(), -3] will not work ([<auto instance>, -3] is used to
create the THIRD enum member)
在 3.11.1 版的變更: 在之前的版本中,auto() 必須是賦值行裡的唯一內容才能運作正確。
可以覆寫 _generate_next_value_ 來客製 auto 使用的值。
備註
In version 3.13 the default _generate_next_value_ will always return
the highest member value incremented by 1, and will fail if any
member is an incompatible type.
-
@enum.property¶
和內建的 @property 相似的裝飾器,但只專門針對列舉。它允許成員屬性和成員本身有相同名稱。
備註
The property and the member must be defined in separate classes;
for example, the value and name attributes are defined in the
Enum class, and Enum subclasses can define members with the
names value and name.
-
@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.verify¶
專門針對列舉的 class 裝飾器。使用 EnumCheck 裡的成員來指定在裝飾的列舉上應該檢查什麼限制。
-
@enum.member¶
列舉所使用的裝飾器:其目標會變成成員。
-
@enum.nonmember¶
列舉所使用的裝飾器:其目標不會變成成員。
-
@enum.global_enum¶
修改列舉的 str() 及 repr() 的裝飾器,讓成員顯示為屬於模組而不是其類別。應該只有當列舉成員被匯出到模組的全域命名空間才使用(範例請參考 re.RegexFlag)。
-
enum.show_flag_values(value)¶
回傳在旗標值中包含的所有 2 的次方的整數串列。
-
enum.bin(num, max_bits=None)¶
與內建的 bin() 類似,但負值以二補數表示,且前導位元永遠表示正負號(0 表示正,1 表示負)。
>>> import enum
>>> enum.bin(10)
'0b0 1010'
>>> enum.bin(~10) # ~10 is -11
'0b1 0101'
IntEnum、StrEnum 及 IntFlag
這三種列舉型別是設計來直接取代現有以整數及字串為基底的值;因此它們有額外的限制:
如果你不需要或不想要這些限制,你可以透過混合 int 或 str 型別來建立自己的基礎類別:
>>> from enum import Enum
>>> class MyIntEnum(int, Enum):
... pass
或者你也可以在你的列舉重新給定合適的 str():
>>> from enum import Enum, IntEnum
>>> class MyIntEnum(IntEnum):
... __str__ = Enum.__str__
© 版權所有 2001 Python Software Foundation.
此頁面採用 Python 軟體基金會授權條款第 2 版。
文件中的範例、應用技巧與其他程式碼額外採用了 Zero Clause BSD 授權條款。
更多訊息請見 歷史與授權條款。
Python 軟體基金會是一家非營利法人。
敬請捐贈。
最後更新於 11月 11, 2026 (06:44 UTC)。
發現 bug?
以 Sphinx8.2.3建立。
|