为什么要 Enum 类
直接用通过类来定义枚举:
class Color():
RED = 1
GREEN = 2
BLUE = 3
print(Color.RED) # 1
会有一些问题:
-
枚举项可以重复出现,后面的会覆盖前面的值
-
枚举项的值可以在外部更改
class Color(): RED = 1 GREEN = 2 BLUE = 3 RED = 11 print(Color.RED) # 11 Color.RED = '红色' print(Color.RED) # 红色
Enum 类
enum模块是系统内置模块,可以直接使用import导入。该模块定义了四个可用于定义唯一名称和值集的枚举类:Enum、IntEnum、Flag和IntFlag 。 它还定义了一个装饰器 unique 和一个帮助器 auto。
Enum
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
print(Color.RED) # Color.RED
print(type(Color.RED)) # <enum 'Color'>
# 枚举类的成员有内置属性name和value
print(Color.RED.name) # RED
print(Color.value) # 1
# 也可以增加其他属性
Color.RED.chinese = '红色'
Enum类中出现同名的成员会报错:
class Color():
RED = 1
RED = 2
# TypeError: Attempted to reuse key: 'SQUARE'
不能在外部修改枚举成员的值:
Color.RED = 5
AttributeError: Cannot reassign members.
枚举类不能用来实例化对象:
c = Color() # error! 枚举类不能用来实例化对象
可以使用 ==
或者 is
来比较枚举成员:
c1 = Color['RED'] # 除了使用.来访问,也可以使用Enum['key']访问枚举成员
c2 = Color(1) # 还可以使用Enum(value)的方式访问枚举成员
c3 = Color.RED
print(c1 == c2 == c3) # True
print(c1 is c2 is c3) # True
枚举支持迭代,按定义顺序:
for c in Color:
print(c.value) # 1,2,3
IntEnum
Enum只能使用 is
, ==
, !=
来进行比较,不能进行有序比较,另外枚举值于非枚举值的比较总是不相等
Color.BLUE == Color.RED # False
Color.BLUE != Color.RED # True
Color.BLUE == Color.BLUE # True
Color.RED == 1 # False
IntEnum除了具有Enum的所有特性,还是int的子类,也就是说可以被当作int来用:
from enum import IntEnum
class Shape(IntEnum):
CIRCLE = 1
SQUARE = 2
class Request(IntEnum):
POST = 1
GET = 2
Shape == 1 # False
Shape.CIRCLE == 1 # True
Shape.CIRCLE >= Request.POST # True
['a', 'b', 'c'][Shape.CIRCLE] # 'b'
l = [i for i in range(Shape.SQUARE)] # l = [0, 1]
auto
可以使用auto来给枚举成员自动设值:
from enum import Enum, auto
class Color(Enum):
RED = auto()
BLUE = auto()
GREEN = auto()
print(list(Color))
[<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]
unique
枚举类中key不能相同,但是value可以相同:
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 1
此时使用Color(1)方式访问到的是RED
如果要限制value也不相同的话,可以使用unique装饰器:
from enum import Enum, unique
@unique
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 1
# ValueError: duplicate values found in <enum 'Color'>: BLUE -> RED
本文由 晓楼 创作,采用 知识共享署名4.0 国际许可协议进行许可。本站文章除注明转载/出处外,均为本站原创或翻译,转载前注明出处