廖雪峰这部分写的有点乱,推荐结合下面博客学习:
https://segmentfault.com/a/1190000017327003
笔记整理于廖雪峰官网和上述博客
定义Enum
- 3.4以前版本pip install enum,from enum import Enum
- 默认枚举成员名对应数值从1开始,如需精准赋值则派生类class Enumname(Enum)
- 成员名不允许重复,成员值允许相同,相同的第二个成员名视为第一个成员的别名。如需成员值唯一则from enum import unique,在定义类前用@unique装饰
- 枚举类型不可以实例化也不可以更改。
from enum import Enum,unique
#value属性是赋给成员的int常量,默认由1开始
#所有枚举类成员名都不能重复
name=Enum('Name',('AAA','BBB','CCC'))
#成员值可以重复,第二个成员名被视为第一个成员的别名
#自定义成员值需要Enum的派生类
class Color(Enum):
Blue=0#value被设定为0,而非默认的1
Pink=0
Red=2
#只能获取到第一个成员名
print(Color.Blue)
#Color.Blue
print(Color.Pink)
#Color.Blue
print(Color(0))
#Color.Blue
@unique#成员值不能重复
class Color(Enum):
Blue=0#value被设定为0
Pink=1
Red=2
枚举取值和比较
- 取值
如下Color类,Color.Blue是成员,Blue是成员的名称属性,常量int 1是成员的值属性。
可以通过成员名或成员值来获取成员
枚举类可以用于迭代,使用Color.__members__.items()可以将名称映射到成员。 - 比较
is或者is not比较,==或者!=比较
Enum成员不能进行大小的比较但成员的value值可以进行大小的比较。
from enum import Enum,unique
@unique#成员值不能重复
class Color(Enum):
Blue=0#value被设定为0
Pink=1
Red=2
#通过成员名获取成员
print(Color.Blue)
#Color.Blue
print(Color['Blue'])
#Color.Blue
#通过成员值获取成员
print(Color(0))
#Color.Blue
#获取成员的名称属性name
print(Color.Red.name)
#Red
#获取成员的值属性value
print(Color.Red.value)
#2
#遍历
for color in Color:
print(color)
#Color.Blue
#Color.Pink
#Color.Red
for color in Color.__members__.items():
print(color)
#('Blue', <Color.Blue: 0>)
#('Pink', <Color.Pink: 1>)
#('Red', <Color.Red: 2>)
for name,member in Color.__members__.items():
print(name,' ',member,' ',member.value)
#Blue Color.Blue 0
#Pink Color.Pink 1
#Red Color.Red 2
#is 、is not、==、!=
Color.Red is Color.Red #True
Color.Red ==Color.Red #True
Color.Red is not Color.Blue #True
Color.Red !=Color.Blue #True
#value可以比较,成员不能比较
Color.Red.value>Color.Blue.value#True
Color.Red>Color.Blue
#TypeError: '>' not supported between instances of 'Color' and 'Color'
扩展枚举 IntEnum
直接复制博客内容https://segmentfault.com/a/1190000017327003
IntEnum可以进行不同类型的整数枚举的比较
from enum import IntEnum
class Shape(IntEnum):
circle = 1
square = 2
class Request(IntEnum):
post = 1
get = 2
print(Shape.circle == 1) # True
print(Shape.circle < 3) # True
print(Shape.circle == Request.post) # True
print(Shape.circle >= Request.post) # True
- 练习
把Student的gender属性改造为枚举类型,可以避免使用字符串:
# -*- coding: utf-8 -*-
from enum import Enum, unique
@unique
class Gender(Enum):
Male = 0
Female = 1
class Student(object):
def __init__(self, name, gender):
self.name = name
# 开始没有考虑到判断类别和报错,直接self.gender=gender
#看讨论才发现这个细节
if (isinstance(gender,Gender)):
self.gender = gender
else:
raise ValueError('gender must be Male(0) or Female(1)!')
# 测试:
bart = Student('Bart', Gender.Male)
if bart.gender == Gender.Male:
print('测试通过!')
else:
print('测试失败!')