【python】Enum 枚举类
Enum 枚举类[1]
Enum
是一组与互不相同的值分别绑定的符号名,类似于全局变量。因为枚举通常表示常量,所以建议枚举成员命名时采用大写。
定义
-
类定义
class Color(Enum): # class syntax RED = 1 GREEN = 2 BLUE = 3
-
方法定义
Color = Enum('Color', ['RED', 'GREEN', 'BLUE']) # functional syntax
-
枚举的成员可以是一个用空格或逗号分隔的字符串(值默认
auto
):'RED GREEN BLUE' | 'RED,GREEN,BLUE' | 'RED, GREEN, BLUE'
-
或是一个名称的迭代器对象:
['RED', 'GREEN', 'BLUE']
-
或是一个 (名称, 值) 对的迭代器对象:
[('CYAN', 4), ('MAGENTA', 5), ('YELLOW', 6)]
-
或是一个映射对象:
{'CHARTREUSE': 7, 'SEA_GREEN': 11, 'ROSEMARY': 42}
-
基本概念
Color = Enum("Color", ["RED", "GREEN"])
assert Color.RED.name == "RED" # 成员的名称
assert Color.GREEN.value == 2 # 成员的值
- 类
Color
是一个 枚举 (或 enum ) - 属性
Color.RED
、Color.GREEN
等是枚举成员,并且在功能上是常量。 - 枚举成员有
names
和values
等属性(Color.RED
的名称是RED
,Color.GREEN
的值是2
)
🗒️ 备注:有些地方会检查是否是真正的
str
而不是str
的子类 (例如使用type(unknown) == str
而不是isinstance(unknown, str)
),在这些地方你将需要使用str(StrEnum.member)
。
基本使用方式
Color = Enum("Color", ["RED", "GREEN"])
assert Color(1) == Color.RED # 通过值查找现有成员
assert Color["GREEN"] == Color.GREEN # 通过名称查找现有成员
assert Color.RED in Color # __contains__
assert list(Color) == [i for i in Color] # __iter__,[<Color.RED: 1>, <Color.GREEN: 2>]
assert len(Color) == 2 # __len__,返回 cls 中成员的数量
list(reversed(Color)) # __reversed__,按定义的逆序返回 cls 中的每个成员
特殊使用方式
auto()
enum.auto
实例被替换为枚举成员的适当值。
StrEnum
默认为成员名称的小写版本,- 而其他枚举默认为 1 并由此递增。
_missing_(cls, value)
缺省值处理
一个用来查找不存在于 cls
中的值的类方法。 在默认情况下它将不做任何事,但可以被重写以实现自定义的搜索行为:
from enum import StrEnum, auto
class Build(StrEnum):
DEBUG = auto()
OPTIMIZED = auto()
UNKNOWN = auto()
@classmethod
def _missing_(cls, value):
value = value.lower()
for member in cls:
if member.value == value:
return member
return cls.UNKNOWN
print(Build.DEBUG) # debug
print(Build('deBUG')) # debug
print(Build('dev')) # unknown
__init__
vs __new__
如果定义了 __new__()
或 __init__()
,则枚举成员的值将被传给这些方法。当你想要定制 Enum
成员的实际值时必须使用 __new__()
。 任何其他修改可以用 __new__()
也可以用 __init__()
,应优先使用 __init__()
。
class Planet(Enum):
MERCURY = (3.303e+23, 2.4397e6)
VENUS = (4.869e+24, 6.0518e6)
EARTH = (5.976e+24, 6.37814e6)
MARS = (6.421e+23, 3.3972e6)
JUPITER = (1.9e+27, 7.1492e7)
SATURN = (5.688e+26, 6.0268e7)
URANUS = (8.686e+25, 2.5559e7)
NEPTUNE = (1.024e+26, 2.4746e7)
def __init__(self, mass, radius):
self.mass = mass # in kilograms
self.radius = radius # in meters
@property
def surface_gravity(self):
G = 6.67300E-11 # universal gravitational constant (m3 kg-1 s-2)
return G * self.mass / (self.radius * self.radius)
Planet.EARTH.value # (5.976e+24, 6378140.0)
Planet.EARTH.surface_gravity # 9.802652743337129
举例来说,如果你要向构造器传入多个条目,但只希望将其中一个作为值:
class Coordinate(bytes, Enum):
"""
Coordinate with binary codes that can be indexed by the int code.
"""
def __new__(cls, value, label, unit):
obj = bytes.__new__(cls, [value])
obj._value_ = value
obj.label = label
obj.unit = unit
return obj
PX = (0, 'P.X', 'km')
PY = (1, 'P.Y', 'km')
VX = (2, 'V.X', 'km/s')
VY = (3, 'V.Y', 'km/s')
print(Coordinate['PY']) # Coordinate.PY
print(Coordinate(3)) # Coordinate.VY
⚠️警告:不要调用
super().__new__()
,因为只能找到仅用于查找的__new__
;请改为直接使用该数据类型。
普通方法和特殊方法
枚举是 Python 的类,可带有普通方法和特殊方法。假设有如下枚举:
class Mood(Enum):
FUNKY = 1
HAPPY = 3
def describe(self):
# self is the member here
return self.name, self.value
def __str__(self):
return 'my custom str! {0}'.format(self.value)
@classmethod
def favorite_mood(cls):
# cls here is the enumeration
return cls.HAPPY
旗标 Flag
为了符合规范,旗标的值必须为二的乘方,且名称不可重复。 因此,除了别名的定义 Enum
之外,没有值 (即 0
) 或是几个二的乘方值之和 (如 3
) 的旗标也会被视为别名。
class Perm(Flag):
R = 4
W = 2
X = 1
A = R|W|X
assert (Perm.R | Perm.W).name == "R|W" # effectively Perm(0)
assert (Perm.R & Perm.W).name is None # effectively Perm(0)
assert bool(Perm.R & Perm(6)) is True
Python 版本:3.11 ↩︎
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具