一、枚举的定义
- 定义枚举,要导入enum模块
- 枚举定义要用class关键字,继承Enum类
- 用于定义枚举的class和定义类的class是有区别的
from enum import Enum
class VIP(Enum):
#枚举:用大写(表示不可更改)
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
print(VIP.BLACK) #VIP.BLACK --枚举的意义所在
代码分析:
- 上面的代码,我定义了VIP类型的枚举类
- 有四个成员,分别是VIP.YELLOW VIP.GREEN VIP.BLACK VIP.RED
- 每个成员都有它各自的名称和值:VIP.YELLOW的名称是:YELLOW,值是:1
- 每个成员的数据类型就是它所属的枚举【*注:用class定义的类,实际上就是一种类型】
与枚举相近的可以采用类变量或者字典,但是他们有不好的地方
- 可变,我们可以轻易的改变它的值;
- 没有防止相同名称的功能。
二、枚举常见问题
2.1.不能改变枚举成员的值
from enum import Enum
class VIP(Enum):
#枚举:用大写
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
VIP.BLACK = 5
运行,会报错
AttributeError: Cannot reassign members.
2.2.定义枚举时,成员名称不允许重复
from enum import Enum
class VIP(Enum):
#枚举:用大写
YELLOW = 1
YELLOW = 6
GREEN = 2
BLACK = 3
RED = 4
运行,会报错
TypeError: Attempted to reuse key: 'YELLOW'
虽然枚举成员的名称不能重复,但是默认情况下,成员的值允许相同,但是两个相同值的成员,第二个成员的名称被视作第一个成员的别名。
from enum import Enum
class VIP(Enum):
#枚举:用大写
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
YELLOW_ALIAS = 1
print(VIP.YELLOW_ALIAS) #VIP.YELLOW
2.3.可以使用@unique装饰器(要导入unique模块),可以帮助我们检查保证没有重复值
from enum import Enum, unique
@unique
class VIP(Enum):
#枚举:用大写
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
BULE = 1
print(VIP.BLACK) #VIP.BLACK --枚举的意义所在
由于使用了@unique装饰器,所以提示我们出现了重复值
ValueError: duplicate values found in <enum 'VIP'>: BULE -> YELLOW
三、枚举取值
from enum import Enum, unique
@unique
class VIP(Enum):
#枚举:用大写
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
#通过成员名称来获取成员
print(VIP['YELLOW']) #VIP.YELLOW
print(type(VIP['YELLOW'])) #<enum 'VIP'>
#通过成员值来获取成员
print(VIP(1)) #VIP.YELLOW
#通过成员来获取成员的名称和值,以及它们的类型
print(VIP.YELLOW) #VIP.YELLOW
print(type((VIP.YELLOW))) #<enum 'VIP'>
print(VIP.YELLOW.name) #YELLOW
print(type(VIP.YELLOW.name)) #<class 'str'>
print(VIP.YELLOW.value) #1
print(type(VIP.YELLOW.value)) #<class 'int'>
注意区分:枚举类型,枚举名称,枚举的值
四、迭代器
4.1.枚举支持迭代器,可以遍历枚举成员
from enum import Enum, unique
@unique
class VIP(Enum):
#枚举:用大写
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
for v in VIP:
print(v)
VIP.YELLOW
VIP.GREEN
VIP.BLACK
VIP.RED
4.2.如果枚举有值重复的成员,循环遍历枚举时只获取值重复成员的第一个成员
from enum import Enum
class VIP(Enum):
#枚举:用大写
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
YELLOW_R = 1
for v in VIP:
print(v)
VIP.YELLOW
VIP.GREEN
VIP.BLACK
VIP.RED
4.3.如果想把值重复的成员也遍历出来,要用枚举的一个特殊属性__members__
from enum import Enum
class VIP(Enum):
#枚举:用大写
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
YELLOW_R = 1
for v in VIP.__members__.items():
print(v)
('YELLOW', <VIP.YELLOW: 1>)
('GREEN', <VIP.GREEN: 2>)
('BLACK', <VIP.BLACK: 3>)
('RED', <VIP.RED: 4>)
('YELLOW_R', <VIP.YELLOW: 1>)
如果不想取这么复杂
from enum import Enum
class VIP(Enum):
#枚举:用大写
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
YELLOW_R = 1
for v in VIP.__members__:
print(v)
YELLOW
GREEN
BLACK
RED
YELLOW_R
五、枚举的运算
from enum import Enum
class VIP(Enum):
#枚举:用大写
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
YELLOW_R = 1
#等值比较
result0 = VIP.YELLOW == VIP.BLACK
print(result0) #False
result1 = VIP.YELLOW == 1 #虽然没有报错,但是值不对
print(result1) #False
result2 = VIP.YELLOW.value == 1
print(result2) #True
#身份比较
result3 = VIP.BLACK is VIP.BLACK
print(result3) #True
#大小比较
result4 = VIP.BLACK > VIP.GREEN
print(result4) #TypeError: '>' not supported between instances of 'VIP' and 'VIP'
#小结:枚举类型不支持大小比较,支持等值比较,身份比较
注意:不同枚举类间的等值比较,虽然值一样,但是它们是不同的
from enum import Enum
class VIP(Enum):
#枚举:用大写
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
YELLOW_R = 1
class VIP1(Enum):
#枚举:用大写
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
YELLOW_R = 1
result = VIP.BLACK == VIP1.BLACK
print(result) #False
六、枚举转换
一般我们会和数据库打交道,将枚举的值存入数据库,或者将枚举的标签即名称以字符串的形式存入数据库。当然我们建议是以前者的方式:更简洁,占用数据库的空间更小。
但是也有部分人不仅在数据库里存入数值,也会在代码里也用这种具体的数值(非常不推荐)
推荐:在代码里显式定义一个枚举类,枚举类下面的每一个枚举类型对应数据库里的每一个数值
---->如何将数值转换成枚举类型
即:通过枚举值来获取枚举成员
from enum import Enum
class VIP(Enum):
#枚举:用大写
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
#假设a是我们从数据库里取出来的数值
a = 3
#枚举转换
print(VIP(a))#通过枚举值来获取枚举成员 VIP.BLACK
七、小知识点
1.IntEnum
from enum import Enum
class VIP(Enum):
#枚举:用大写
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
BLUE = 'blue'
print(VIP.BLUE.value) #blue
print(type(VIP.BLUE.value)) #<class 'str'>
在上面代码中,我们也可以将枚举的值定为str,假如我们想要值都为数值,不允许为str,可以用IntEnum
from enum import IntEnum
class VIP(IntEnum):
#枚举:用大写
YELLOW = 1
GREEN = 2
BLACK = 3
RED = 4
BLUE = 'blue'
#报错:ValueError: invalid literal for int() with base 10: 'blue'
2.python中的枚举类型是单例模式,不能够实例化