内置枚举类Enum

使用内置的枚举类Enum,需要引入enum模块。

例如:

1
2
3
4
5
6
7
8
from enum import Enum
#Enum函数新建枚举Month
Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
#枚举Month的类型
print(type(Month))
#循环打印枚举
for name, member in Month.__members__.items():
    print(name, '=>', member, ',', member.value)

执行以上程序会输出如下结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<class 'enum.EnumMeta'>
Jan => Month.Jan , 1
Feb => Month.Feb , 2
Mar => Month.Mar , 3
Apr => Month.Apr , 4
May => Month.May , 5
Jun => Month.Jun , 6
Jul => Month.Jul , 7
Aug => Month.Aug , 8
Sep => Month.Sep , 9
Oct => Month.Oct , 10
Nov => Month.Nov , 11
Dec => Month.Dec , 12

value属性则是自动赋给成员的int常量,默认从1开始计数。

自定义枚举类

如果需要更精确地控制枚举类型,可以从Enum派生出自定义类:

1.枚举的定义
枚举定义用class关键字,继承Enum类。

例如:

1
2
3
4
5
6
7
8
9
from enum import Enum
class Weekday(Enum):
    Sun = 0
    Mon = 1
    Tue = 2
    Wed = 3
    Thu = 4
    Fri = 5
    Sat = 6

代码分析: 上面的代码,我们定义了枚举Weekday。Weekday枚举有7个成员,分别是Weekday.Sun、Weekday.Mon等。每一个成员都有它们各自名称和值,Weekday.Sun成员的名称是:Sun,值是:0。每个成员的数据类型就是它所属的枚举。

1.1 定义枚举时,成员名称不允许重复

例如:

1
2
3
4
from enum import Enum
class Weekday(Enum):
    Mon = 1
    Mon = 2

上面的代码,就无法执行。提示错误:

1
2
3
4
5
6
7
8
Traceback (most recent call last):
  File "main.py", line 2, in <module>
    class Weekday(Enum):
  File "main.py", line 4, in Weekday
    Mon = 2
  File "/usr/lib64/python3.6/enum.py", line 92, in __setitem__
    raise TypeError('Attempted to reuse key: %r' % key)
TypeError: Attempted to reuse key: 'Mon'

1.2 默认情况下,不同的成员值允许相同。但是两个相同值的成员,第二个成员的名称被视作第一个成员的别名

例如:

1
2
3
4
from enum import Enum
class Weekday(Enum):
    Mon = 1
    Mon_alias = 1

Weekday.Mon_alias的名称Mon_alias就被视作成员Weekday.Mon名称Mon的别名。

1.3 如果枚举中存在相同值的成员,在通过值获取枚举成员时,只能获取到第一个成员

例如:

1
2
3
4
5
from enum import Enum
class Weekday(Enum):
    Mon = 1
    Mon_alias = 1
print(Weekday(1))

输出结果为:Weekday.Mon

1.4 如果要限制定义枚举时,不能定义相同值的成员。可以使用装饰器@unique

例如:

1
2
3
4
5
from enum import Enum, unique
@unique
class Weekday(Enum):
    Mon = 1
    Mon_alias = 1

再执行就会提示错误:

1
2
3
4
5
6
Traceback (most recent call last):
  File "main.py", line 3, in <module>
    class Weekday(Enum):
  File "/usr/lib64/python3.6/enum.py", line 834, in unique
    (enumeration, alias_details))
ValueError: duplicate values found in <enum 'Weekday'>: Mon_alias -> Mon

2.枚举取值
通过成员的名称来获取成员
Weekday[‘Mon’]

通过成员值来获取成员
Weekday(1)

通过成员,来获取它的名称和值
Mon_member = Weekday.Mon
Mon_member.name
Mon_member.value

3.迭代器
3.1 枚举支持迭代器,可以遍历枚举成员

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from enum import Enum
class Weekday(Enum):
    Sun = 0
    Mon = 1
    Tue = 2
    Wed = 3
    Thu = 4
    Fri = 5
    Sat = 6

for day in Weekday:
    print(day)

输出结果是,枚举的所有成员。

1
2
3
4
5
6
7
Weekday.Sun
Weekday.Mon
Weekday.Tue
Weekday.Wed
Weekday.Thu
Weekday.Fri
Weekday.Sat

3.2 如果枚举有值重复的成员,循环遍历枚举时只获取值重复成员的第一个成员

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
from enum import Enum
class Weekday(Enum):
    Sun = 0
    Mon = 1
    Tue = 2
    Wed = 3
    Thu = 4
    Fri = 5
    Sat = 6
    Mon_alias = 1

for day in Weekday:
    print(day)

输出结果是:

1
2
3
4
5
6
7
Weekday.Sun
Weekday.Mon
Weekday.Tue
Weekday.Wed
Weekday.Thu
Weekday.Fri
Weekday.Sat

但是Weekday.Mon_alias并没有出现在输出结果中。

3.3 如果想把值重复的成员也遍历出来,要用枚举的一个特殊属性members

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
from enum import Enum
class Weekday(Enum):
    Sun = 0
    Mon = 1
    Tue = 2
    Wed = 3
    Thu = 4
    Fri = 5
    Sat = 6
    Mon_alias = 1

for day in Weekday:
    print(day)

for day in Weekday.__members__.items():
    print(day)

输出结果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
Weekday.Sun
Weekday.Mon
Weekday.Tue
Weekday.Wed
Weekday.Thu
Weekday.Fri
Weekday.Sat
('Sun', <Weekday.Sun: 0>)
('Mon', <Weekday.Mon: 1>)
('Tue', <Weekday.Tue: 2>)
('Wed', <Weekday.Wed: 3>)
('Thu', <Weekday.Thu: 4>)
('Fri', <Weekday.Fri: 5>)
('Sat', <Weekday.Sat: 6>)
('Mon_alias', <Weekday.Mon: 1>)

4.枚举比较
4.1 枚举成员可进行同一性比较
Weekday.Mon is Weekday.Mon
输出结果是:True

Weekday.Mon is not Weekday.Sat
输出结果是:True

4.2 枚举成员可进行等值比较
Weekday.Mon == Weekday.Sat
输出结果是:False

Weekday.Mon != Weekday.Sat
输出结果是:True

4.3 枚举成员不能进行大小比较
Weekday.Mon < Weekday.Sat
输出结果出错:TypeError: unorderable types: Weekday() < Weekday() ​


转载请注明本网址。