enum --- 對列舉的支援

在 3.4 版被加入.

原始碼:Lib/enum.py


列舉:

  • 是一組綁定唯一值的代表名稱(成員)

  • 可以用疊代的方式以定義的順序回傳其正式 (canonical)(即非別名)成員

  • 使用 call 語法來透過值回傳成員

  • 使用 index 語法來透過名稱回傳成員

列舉透過 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 類別。參考列舉有何差異以取得更多細節。

備註

命名方式

  • Color 類別是一個列舉(或 enum

  • Color.REDColor.GREEN 等屬性是列舉成員(或成員),並且使用上可以看作常數。

  • 列舉成員有名稱Color.RED 的名稱是 REDColor.BLUE 的值是 3 諸如此類)


模組內容

EnumType

Enum 及其子類別的 type

Enum

用來建立列舉常數的基礎類別。

IntEnum

用來建立列舉常數的基礎類別,同時也是 int 的子類別。(備註

StrEnum

用來建立列舉常數的基礎類別,同時也是 str 的子類別。(備註

Flag

用來建立列舉常數的基礎類別,可以使用位元操作來結合成員且其結果不失去 Flag 的成員資格。

IntFlag

用來建立列舉常數的基礎類別,可以使用位元操作來結合成員且其結果不失去 IntFlag 的成員資格。IntFlag 的成員也是 int 的子類別。(備註

ReprEnum

IntEnumStrEnumIntFlag 所使用來保留這些混合型別的 str()

EnumCheck

一個有 CONTINUOUSNAMED_FLAGSUNIQUE 這些值的列舉,和 verify() 一起使用來確保給定的列舉符合多種限制。

FlagBoundary

一個有 STRICTCONFORMEJECTKEEP 這些值的列舉,允許列舉對如何處理非法值做更細微的控制。

EnumDict

dict 的子類別,用於當作 EnumType 的子類別時使用。

auto

列舉成員的實例會被取代成合適的值。StrEnum 預設是小寫版本的成員名稱,其它列舉則預設是 1 且往後遞增。

property()

允許 Enum 成員擁有屬性且不會與成員名稱有衝突。valuename 屬性是用這個方式來實作。

unique()

Enum 類別的裝飾器,用來確保任何值只有綁定到一個名稱上。

verify()

Enum 類別的裝飾器,用來檢查列舉上使用者所選的限制。

member()

obj 變成成員。可以當作裝飾器使用。

nonmember()

不讓 obj 變成成員。可以當作裝飾器使用。

global_enum()

修改列舉上的 str()repr() ,讓成員顯示為屬於模組而不是類別,並將該列舉成員匯出到全域命名空間。

show_flag_values()

回傳旗標 (flag) 裡包含的所有 2 的次方的整數串列。

enum.bin()

與內建的 bin() 類似,但負值以二補數表示,且前導位元永遠表示正負號(0 表示正,1 表示負)。

在 3.6 版被加入: Flag, IntFlag, auto

在 3.11 版被加入: StrEnum, EnumCheck, ReprEnum, FlagBoundary, property, member, nonmember, global_enum, show_flag_values

在 3.13 版被加入: EnumDict


資料型別

class enum.EnumType

EnumTypeenum 列舉的 metaclassEnumType 可以有子類別 -- 細節請參考 建立 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)

這個方法可以用兩種不同的方式呼叫:

  • 查詢已存在的成員:

    cls:

    所呼叫的列舉類別。

    value:

    要查詢的值。

  • 使用 cls 列舉來建立新列舉(只有在現有列舉沒有任何成員時)

    cls:

    所呼叫的列舉類別。

    value:

    要建立的新列舉的名稱。

    names:

    新列舉的成員的名稱/值。

    module:

    新列舉要建立在哪個模組名稱下。

    qualname:

    這個列舉在模組裡實際上的位置。

    type:

    新列舉的混合型別。

    start:

    列舉的第一個整數值(由 auto 所使用)

    boundary:

    在位元操作時怎麼處理範圍外的值(只有 Flag 會用到)

__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 的成員數量:

>>> len(Color)
3
__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 成員給定的值:

>>> Color.RED.value
1

成員的值,可以在 __new__() 設定。

備註

列舉成員的值

成員的值可以是任何值:intstr 等等。如果實際使用什麼值並不重要,你可以使用 auto 實例,它會為你選擇合適的值。更多細節請參考 auto

雖然可以使用可變的 (mutable) / 不可雜湊的 (unhashable) 值,例如 dictlist 或可變的 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.

在 3.6 版被加入.

_ignore_

_ignore_ 只有在建立的時候用到,在列舉建立完成後會被移除。

_ignore_ 是一個不會變成成員的名稱串列,在列舉建立完成後其名稱會被移除。範例請參考 TimePeriod

在 3.7 版被加入.

__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.6 版被加入.

在 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'>

在 3.6 版被加入.

__new__(