# Python小技巧
大家好呀,今天是2021年的最后一天啦!预祝大家元旦快乐的同时,咱们的更新也是不能间断
的~于是给大家聊聊新学的知识点: 枚举类
.
# 读法
英式英语: 椅娜姆 [ɪˌnjuːm]
美式读音: 饿呢母 ['enəm]
# 枚举的概念
枚举在别的语言中都是很常见
的,不知道我当时学Python的时候是不是还没有(也可能我没学到)。先来说说什么是枚举:
在数学和计算机科学理论中,一个集的枚举是列出某些有穷序列集的所有成员的程序,或者是一种特定类型对象的计数。这两种类型经常(但不总是)重叠。
听起来有点晦涩,其实就是列举一组数据的所有可能出现的类型
。我们来看一个生动的例子:
东南西北
在不考虑东北,东南这样的
组合方向
时,我们其实只有4种方向。星期
同理我们来看看星期X,只可能是星期一到星期天,也就是7种数据。
枚举的意义就是把我们所有可能出现的
类型
都提前准备好,以备不时之需。理解了概念之后,我们来看一个具体的应用:
# 枚举的应用
假设我们这时候要记录一个物体的朝向
,体现在数据库的话,可能会用0,1,2,3代表东南西北。
假设我们判断方向,我们可能这么写:
# 数据库中的Thing(物体对象)
a = Thing()
if a.position == 1:
print("魔法伤害")
2
3
4
大家看看这样的代码,有没有觉得有什么问题
?虽然他能很好地运转,但是仔细想想,过1个月,你再来看,你可能不太清楚1代表南方还是北方。
有的导弹鬼会说:东南西北,1肯定是南哦!
是没错,但是你想,你组里来了个新人,人家从小背的就是东西南北。他觉得1是西呢?再或者,有个新人习惯性所有数据从1开始,也就是东南西北分别对应1234
。
所以这样会给咱们带来一个可读障碍
。
那我们换成枚举类,会怎么样呢?show you the code!
from enum import Enum
class Position(Enum):
east = 0
south = 1
west = 2
north = 3
a = Thing()
if a.postion == Postion.south:
print("魔法伤害")
2
3
4
5
6
7
8
9
10
11
12
我们来解析下代码:
- 我们引入了Enum类
- 定义了一个类并继承自Enum
- 里面很简单,定义东南西北,分别为0123
这样写的话,来了新人(再憨憨)也知道你判断的是位置是不是南方
。
# 存在的问题
但其实这样写是不对的,Enum类只能和Enum类进行比较。我们看看这样的输出:
惊不惊喜,意不意外?没错,枚举类是只能和枚举类比较,那我们怎么解决这个问题呢?
# IntEnum
别担心,除了枚举类,我们还有继承自Enum的IntEnum
,我们改改代码:
注意改动处,我们只是换了个父类。
# unique
有的导弹鬼很坏,他问,我可能手滑,复制错了,比如south写成了1,west也写成了1,能不能给我点提示啊?
当然是有的!!!
我们引入unique装饰器,放到枚举类上:
可以看到提醒你2个数据重复啦!!!
# 提高可读性
有人说,这里面定义英文名很难受
诶。我就想看东南西北!!!我们可以改写Position的__str__方法,并给个静态方法:
from enum import IntEnum, unique
@unique
class Position(IntEnum):
east = 0
south = 1
west = 2
north = 3
def __str__(self):
if self.value == self.east:
return "东"
if self.value == self.south:
return "南"
if self.value == self.west:
return "西"
if self.value == self.north:
return "北"
raise Exception("枚举值错误")
@property
def desc(self):
return self.__str__()
print(Position.east)
print(Position.east.name)
print(Position.east.value)
print(Position.east.desc == "东")
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
可以看到,我们新增了__str__和desc方法,其实这里if很多,我们在Python3.10
可以替换为switch.
看看执行结果:
# 如果我们想要英文south
,就调用name属性,想要数字value就调用value属性,要中文名称调用desc即可。
今天的枚举类就介绍到这里了,大家有兴趣可以看看enum里面的其他东西。祝大家元旦快乐
~~