enum
--- 对枚举的支持¶
在 3.4 版本加入。
源代码: Lib/enum.py
枚举
是绑定到唯一值的符号名称(成员)的集合
可以被迭代以按定义顺序返回其规范(即非别名)成员
使用*调用*语法按值返回成员
使用*索引*语法按名称返回成员
枚举可以通过使用 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
等,是*枚举成员* (或 *members*),在功能上是常量。枚举成员有*名称*和*值*(
Color.RED
的名称是RED
,Color.BLUE
的值是3
,等等)
模块内容¶
Enum 及其子类的
type
。用于创建枚举常量的基类。
用于创建枚举常量的基类,这些常量可以使用按位运算进行组合,而不会失去其
Flag
成员资格。一个值为
CONTINUOUS
、NAMED_FLAGS
和UNIQUE
的枚举,与verify()
一起使用,以确保给定枚举满足各种约束。一个值为
STRICT
、CONFORM
、EJECT
和KEEP
的枚举,允许更精细地控制枚举中如何处理无效值。实例会被替换为适合 Enum 成员的值。
StrEnum
默认为成员名称的小写版本,而其他枚举默认为 1 并从此递增。允许
Enum
成员拥有属性而不与成员名称冲突。value
和name
属性就是这样实现的。枚举类的装饰器,确保只有一个名称绑定到任何一个值。
枚举类的装饰器,用于检查枚举上用户可选择的约束。
使
obj
成为一个成员。可以用作装饰器。不使
obj
成为一个成员。可用作装饰器。返回标志中包含的所有2的幂的整数列表。
在 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¶
EnumType 是*枚举*的 元类。可以子类化 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)¶
此方法以两种不同的方式被调用
查找一个现有的成员
- cls:
被调用的枚举类。
- value:
要查找的值。
使用
cls
枚举创建一个新的枚举(仅当现有枚举没有任何成员时)
- __contains__(cls, member)¶
如果成员属于
cls
,则返回True
>>> some_var = Color.RED >>> some_var in Color True >>> Color.RED.value in Color True
在 3.12 版本发生变更: 在 Python 3.12 之前,如果在包含性检查中使用非枚举成员,会引发
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>]
- class enum.Enum¶
Enum 是所有*枚举*的基类。
- name¶
用于定义
Enum
成员的名称>>> Color.BLUE.name 'BLUE'
- _name_¶
成员的名称。
- _order_¶
不再使用,为向后兼容而保留。(类属性,在类创建期间被移除)。
- _ignore_¶
_ignore_
仅在创建期间使用,并在创建完成后从枚举中移除。_ignore_
是一个名称列表,这些名称不会成为成员,并且其名称也将从完成的枚举中移除。请参阅 TimePeriod 示例。
- __dir__(self)¶
返回
['__class__', '__doc__', '__module__', 'name', 'value']
以及在 self.__class__ 上定义的任何公共方法>>> from enum import Enum >>> 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, 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
- __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)¶
默认情况下,不存在。如果指定,无论是在枚举类定义中还是在混入类中(例如
int
),成员赋值中给出的所有值都将被传递;例如>>> from enum import Enum >>> class MyIntEnum(int, Enum): ... TWENTYSIX = '1a', 16
结果是对
int('1a', 16)
的调用,成员的值为26
。备注
当编写自定义
__new__
时,不要使用super().__new__
—— 而是调用相应的__new__
。
- __repr__(self)¶
返回用于 repr() 调用的字符串。默认情况下,返回*枚举*名称、成员名称和值,但可以被重写
>>> 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() 调用的字符串。默认情况下,返回*枚举*名称和成员名称,但可以被重写
>>> 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')
在 3.12 版本发生变更: 添加了数据类支持
- _add_alias_()¶
将一个新名称作为现有成员的别名添加
>>> Color.RED._add_alias_("ERROR") >>> Color.ERROR <Color.RED: 1>
如果名称已分配给不同的成员,则引发
NameError
。在 3.13 版本加入。
- _add_value_alias_()¶
将一个新值作为现有成员的别名添加
>>> Color.RED._add_value_alias_(42) >>> Color(42) <Color.RED: 1>
如果该值已与不同成员关联,则引发
ValueError
。在 3.13 版本加入。
- 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 版本发生变更:
__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'
备注
标准库中有一些地方会检查确切的
str
而不是str
子类(即type(unknown) == str
而不是isinstance(unknown, str)
),在这些地方你需要使用str(MyStrEnum.MY_MEMBER)
。备注
为了更好地支持*替换现有常量*的用例,
__str__()
是str.__str__()
。出于同样的原因,__format__()
同样是str.__format__()
。在 3.11 版本中新增。
- class enum.Flag¶
Flag
与Enum
相同,但其成员支持位运算符&
(*与*),|
(*或*),^
(*异或*) 和~
(*取反*);这些操作的结果是枚举的成员(的别名)。- __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)¶
返回当前标志与另一个标志进行二进制或运算的结果
>>> Color.RED | Color.GREEN <Color.RED|GREEN: 3>
- __and__(self, other)¶
返回当前标志与另一个标志进行二进制与运算的结果
>>> purple & white <Color.RED|BLUE: 5> >>> purple & Color.GREEN <Color: 0>
- __xor__(self, other)¶
返回当前标志与另一个标志进行二进制异或运算的结果
>>> 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>
在 3.11 版本发生变更: 零值标志的 *repr()* 已更改。现在是
>>> Color(0) <Color: 0>
- 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
>>> Color.RED + 2 3
如果对一个 IntFlag 成员执行一个
Flag
操作并且结果是有效的 IntFlag:返回一个 IntFlag
结果不是有效的 IntFlag:结果取决于
FlagBoundary
设置
未命名的零值标志的
repr()
已更改。现在是>>> Color(0) <Color: 0>
在 3.11 版本发生变更:
__str__()
现在是int.__str__()
,以更好地支持*替换现有常量*的用例。__format__()
出于同样的原因,已经是int.__format__()
。IntFlag
的反转现在返回一个正值,该值是所有不在给定标志中的标志的并集,而不是一个负值。这与现有的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
控制在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¶
-
>>> 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>
在 3.11 版本中新增。
- class enum.EnumDict¶
EnumDict 是
dict
的子类,用作定义枚举类的命名空间(参见准备类命名空间)。它被公开以允许EnumType
的子类具有高级行为,例如每个成员有多个值。调用时应提供正在创建的枚举类的名称,否则私有名称和内部类将无法正确处理。请注意,只有
MutableMapping
接口(__setitem__()
和update()
)被重写。可能会通过其他dict
操作(如|=
)绕过检查。- member_names¶
一个成员名称的列表。
在 3.13 版本加入。
受支持的 __dunder__
名称¶
__members__
是一个只读的有序映射,包含 member_name
:member
项。它仅在类上可用。
__new__()
,如果指定,必须创建并返回枚举成员;同时,适当地设置成员的 _value_
也是一个很好的做法。一旦所有成员都创建完毕,它就不再被使用。
支持的 _sunder_
名称¶
_name_
-- 成员的名称_value_
-- 成员的值;可以在__new__
中设置_missing_()
-- 当未找到值时使用的查找函数;可以被重写_order_
– 已不再使用,为保持向后兼容而保留(类属性,在类创建期间被移除)_generate_next_value_()
– 用于为枚举成员获取适当的值;可以被重写_add_alias_()
– 将一个新名称作为现有成员的别名添加。_add_value_alias_()
– 将一个新值作为现有成员的别名添加。虽然
_sunder_
名称通常保留用于Enum
类的进一步开发,不能使用,但有些是明确允许的_repr_*
(例如_repr_html_
), 如在 IPython的富文本显示 中使用
在 3.6 版本加入: _missing_
, _order_
, _generate_next_value_
在 3.7 版本加入: _ignore_
在 3.13 版本加入: _add_alias_
, _add_value_alias_
, _repr_*
工具与装饰器¶
- class enum.auto¶
auto 可以用来代替一个值。如果使用,Enum 机制将调用一个
Enum
的_generate_next_value_()
来获取一个适当的值。对于Enum
和IntEnum
,这个适当的值将是最后一个值加一;对于Flag
和IntFlag
,它将是大于最高值的第一个二的幂;对于StrEnum
,它将是成员名称的小写版本。如果将 auto() 与手动指定的值混合使用,必须小心。auto 实例仅在赋值的顶层被解析
FIRST = auto()
会工作 (auto() 被替换为1
);SECOND = auto(), -2
会工作 (auto 被替换为2
, 所以2, -2
被用来创建SECOND
枚举成员;THREE = [auto(), -3]
将*不*工作 (<auto instance>, -3
被用来创建THREE
枚举成员)
在 3.11.1 版本发生变更: 在早期版本中,
auto()
必须是赋值行上的唯一内容才能正常工作。_generate_next_value_
可以被重写以自定义 auto 使用的值。备注
在 3.13 中,默认的
_generate_next_value_
将总是返回最高成员值加 1,如果任何成员是不兼容的类型,则会失败。
- @enum.property¶
一个类似于内置 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)¶
返回一个标志 *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__