Python3学习(27)--枚举类型
枚举类型:
一组数量有限的标识符来表示一组连续的整型常数,使能够更清晰的表示出现实世界。
比如,我们知道颜色Color,有Red、Black、Blue、Green、Pink等,因此,我们可以为Color创建一组枚举变量如下(C#版本):
class Program
{
enum Color
{
Red, //默认不赋值 value从0开始,下面枚举变量的整数值依次递增
Black,
Blue = 1,//如果中间一个枚举变量赋值,下面的枚举变量的整数值从赋值处开始依次递增
Green,
Pink
}
/* name:Red member:Color.Red value:0 */
static void Main(string[] args)
{
Console.WriteLine(Color.Red + " : " + Convert.ToInt32(Color.Red));
Console.WriteLine(Color.Black + " : " + Convert.ToInt32(Color.Black));
Console.WriteLine(Color.Green + " : " + Convert.ToInt32(Color.Green));
Console.WriteLine(Color.Pink + " : " + Convert.ToInt32(Color.Pink));
}
}
再比如,我们知道一周有7天,周一到周日,这些是固定的,相当于常量一样,但是如果我们用整数1表示周一,可能我们自己知道1代表什么,对外的话,别人看见了,可能会认为1就是一个int,还可能认为1代表的就是True,或者表示的是一个元组索引.....
但如果我们用标识符Monday表示周一的话,是不是就通用了,大家一看到这个,就知道表示的是什么。
数据模型:
Weekend:
('Mon','Tues','Wed','Thurs','Fri','Sat','Sun')
ok,我们试图在Python中使用枚举类型,但是我们发现,Python中并没有直接提供Enum变量或者类,需要导入enum模块中的Enum类才能使用Enum枚举类型,下面讲个小插曲:
enum.py:
#!/usr/bin/env Python3
# -*- encoding:UTF-8 -*-
from enum import Enum
注意,此时你的py文件叫enum,我们看下,上述的demo能否通过编译
如果你不小心定义的模块名称和系统的或者第三方模块的名称冲突了(前面讲模块的时候提到过),那么恭喜你,中奖了,你不要怀疑是不是系统模块enum没有安装啊?是不是需要重新利用pip管理模块工具下载最新版本啊?不要怀疑自己的Python和其他人的不一样,我们看下,系统的enum.py是否存在:
ok,我们赶紧把我们的py文件名改一下,如下:
enum_test.py:
使用Enum枚举类型之前,我们看一下,help函数给我们提供的Enum类信息:
看了之后,是不是心里有底了,下面,我们直接上demo,定义一个枚举类型 WeekEnd,并指定这个枚举类型的类标识也是'WeekEnd'(保持一致),然后,我们列举枚举变量(标识符),当然,Python的枚举变量默认int值是从1开始的(区别于C#的),最后,我们通过__members__容器,取出(items)其中的name和value映射,当然,还有一个属性是,卖个关子,我们上代码;
enum_test.py:
#!/usr/bin/env Python3
# -*- encoding:UTF-8 -*-
from enum import Enum
WeekEnd = Enum('WeekEnd', ('Mon','Tues','Wed','Thurs','Fri','Sat','Sun'))
for name,member in WeekEnd.__members__.items():
print(name,'==>',member.value,'==>',member)
注意,Enum是一个类,WeekEnd是Enum类的实例,当然,Enum不是普通的类,它表示一个枚举器,因此,我们要指定第一个参数'WeekEnd',表示当前的枚举器的class描述为WeekEnd,而后面紧跟的就是这个枚举器WeekEnd的成员members,因此,我们要想得到成员的名称,我们用name,如果我们想得到成员对应的int值,我们得用member.value而不是name.value,我们看下执行结果:
默认枚举成员的整数值member.value从1开始(如果不指定的话),如果,我们改变枚举类型的class描述,member成员也会跟着发生改变:
如果我们想要让枚举成员的value不从1开始,而是从0开始,我们可以自己定义一个类WeekEnd,继承自Enum,同时,我们使用类的装饰器@unique来帮助我们检查类中定义的枚举成员变量的值是否有重复的,我们看下如下demo:
Week.py:
#!/usr/bin/env Python3
# -*- encoding:UTF-8 -*-
from enum import Enum,unique
@unique
class WeekEnd(Enum):
Sun = 0
Mon = 1
Tue =2
Wed = 3
Thu = 4
Fri = 5
Sat =6
我们看下,如果我们在类WeekEnd里面,将成员变量Sun和Mon的值设置为一样,会这么样:
ok,所以说,装饰器不仅可以扩展函数,还可以在类上作用。
Pyhon中的枚举成员有好几种访问形式,我们直接上demo:
Week.py:
#!/usr/bin/env Python3
# -*- encoding:UTF-8 -*-
from enum import Enum,unique
@unique
class WeekEnd(Enum):
Sun = 0
Mon = 1
Tue =2
Wed = 3
Thu = 4
Fri = 5
Sat =6
#由于WeekEnd继承自枚举类型Enum,因此,具备了枚举类型的特性,有name、value ==>member
print(type(WeekEnd))
#直接用类访问自己的成员member以及member.value
print(WeekEnd.Mon)
print(WeekEnd.Mon.value)
#利用 类[name],获得对应name的member,类[name].value = member.value
print(WeekEnd['Mon'])
print(WeekEnd['Mon'].value)
#利用 类(member.value),反过来获得member,类(member.value).value = member.value
print(WeekEnd(6))
print(WeekEnd(6).value)
#type(member.value) = int类型
print(1==WeekEnd.Mon.value)
我们看下效果:
当然,如果访问到了一个不存在的枚举成员,会抛出ValueError异常:
本篇结束!