- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章一文读懂Python 枚举由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
enum 是一组绑定到唯一常数值的符号名称,并且具备可迭代性和可比较性的特性。我们可以使用 enum 创建具有良好定义的标识符,而不是直接使用魔法字符串或整数,也便于开发工程师的代码维护.
创建枚举 。
我们可以使用 class 语法创建一个枚举类型,方便我们进行读写,另外,根据函数 API 的描述定义,我们可以创建一个 enum 的子类,如下:
1
2
3
4
5
6
7
8
9
|
from
enum
import
Enum
class
HttpStatus(Enum):
OK
=
200
BAD_REQUEST
=
400
FORBIDDEN
=
403
NOT_FOUND
=
404
REQUEST_TIMEOUT
=
408
SERVICE_UNAVAILABLE
=
500
|
注意: 枚举属性值可以是任何东西: int, str 等。如果确切的值不重要,您可以使用 auto 实例,并为您选择适当的值。如果您将 auto 与其他值混合,则必须小心。 枚举类型中,不可以设置相同名称的 name,可以有相同的 value.
enum 自带属性 name 和 value,日常工作中使用最多的也是这两个属性,我们打印看看结果:
1
2
3
4
5
6
|
print
(
'Member: {}'
.
format
(HttpStatus.OK))
# Member: HttpStatus.OK
print
(
'Member name: {}'
.
format
(HttpStatus.OK.name))
# Member name: OK
print
(
'Member value: {}'
.
format
(HttpStatus.OK.value))
# Member value: 200
print
(
repr
(HttpStatus.OK))
# <enum 'HttpStatus'>
print
(
type
(HttpStatus.OK))
# <HttpStatus.OK: 200>
print
(
isinstance
(HttpStatus.OK, HttpStatus))
# True
|
枚举迭代 。
枚举支持迭代和遍历顺序。举个例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
from
enum
import
Enum, auto
# 创建
class
HttpStatus(Enum):
OK
=
200
BAD_REQUEST
=
400
FORBIDDEN
=
403
NOT_FOUND
=
404
REQUEST_TIMEOUT
=
408
SERVICE_UNAVAILABLE
=
500
OTHER
=
auto.value
# 迭代
for
status
in
HttpStatus:
print
(
'{} : {}'
.
format
(status.name, status.value))
|
打印结果:
OK : 200 BAD_REQUEST : 400 FORBIDDEN : 403 NOT_FOUND : 404 REQUEST_TIMEOUT : 408 SERVICE_UNAVAILABLE : 500 OTHER : <object object at 0x000002863E1D7B10> 。
可以看出,遍历的每一个 status 是一个独立的枚举成员,拥有 name 和 value 属性.
另外,我们也可以使用如下形式来进行枚举遍历:
1
2
|
for
name, member
in
HttpStatus.__members__.items():
print
(
'{} : {}'
.
format
(name, member))
|
枚举成员与属性访问 。
通过枚举 value 进行访问,访问需要使用元组()的形式 。
1
|
print
(HttpStatus(
200
))
# HttpStatus.OK
|
通过枚举 name 进行访问,访问需要使用列表[]的形式 。
1
|
print
(HttpStatus[
'OK'
])
# HttpStatus.OK
|
将属性赋予另一个 enum 成员 。
1
2
|
number
=
HttpStatus.OK
print
(number)
# HttpStatus.OK
|
枚举值唯一 。
上面我们创建的枚举类中,value 值是可以重复的,如果我们不想枚举类中的值重复可以是用装饰器 @unique,举例如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
from
enum
import
Enum, unique
# 创建
@unique
class
HttpStatus(Enum):
OK
=
200
BAD_REQUEST
=
400
FORBIDDEN
=
403
NOT_FOUND
=
404
REQUEST_TIMEOUT
=
408
SERVICE_UNAVAILABLE
=
500
OTHER
=
200
|
我们运行后,报如下异常:
ValueError: duplicate values found in <enum 'HttpStatus'>: OTHER -> OK 。
我们查看源代码,发现加入此装饰器的枚举类型,unique 方法会将其 __members__.items() 进行遍历,追加到 duplicates 列表中,如果发现列表不为空,则抛出如上异常信息.
枚举自动赋值 。
此功能用于我们在使用枚举时,只在意枚举的标识符的含义而不在意值的情况下,但是如果需要与字符串或整数混合使用就要额外注意。下面贴上官方的示例:
1
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
|
import
unittest
from
enum
import
auto, Enum
class
TestEnum(unittest.TestCase):
def
test_auto_number(
self
):
class
Color(Enum):
red
=
auto()
blue
=
auto()
green
=
auto()
self
.assertEqual(
list
(Color), [Color.red, Color.blue, Color.green])
self
.assertEqual(Color.red.value,
1
)
self
.assertEqual(Color.blue.value,
2
)
self
.assertEqual(Color.green.value,
3
)
def
test_auto_name(
self
):
class
Color(Enum):
def
_generate_next_value_(
self
, start, count, last):
return
self
red
=
auto()
blue
=
auto()
green
=
auto()
self
.assertEqual(
list
(Color), [Color.red, Color.blue, Color.green])
self
.assertEqual(Color.red.value,
'red'
)
self
.assertEqual(Color.blue.value,
'blue'
)
self
.assertEqual(Color.green.value,
'green'
)
|
可以发现,使用 auto() 得到的是整数自增型,如果我们需要别的方式,只需要在我们的枚举类中,重写 _generate_next_value_ 方法.
枚举比较 。
枚举对象可以进行比较,但是不能进行值比较,如果需要进行值比较则需要枚举对象继承 IntEnum 对象,举个例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import
unittest
from
enum
import
Enum, IntEnum
class
TestEnum(unittest.TestCase):
class
Season(IntEnum):
SPRING
=
1
SUMMER
=
2
AUTUMN
=
3
WINTER
=
4
def
test_comparisons(
self
):
season
=
self
.Season
self
.assertEqual(season.SPRING,
1
)
class
Part(Enum):
SPRING
=
1
CLIP
=
2
BARREL
=
3
self
.assertNotEqual(Part.SPRING,
1
)
self
.assertNotEqual(Part.SPRING, season.SPRING)
TestEnum().test_comparisons()
|
上面的测试例子当中,我们创建了两个继承类型不一样的枚举类,可以看到继承了 IntEnum 的 Season 可以进行值的比较,而继承了 Enum 的 Part 则不能进行值比较,并且 IntEnum 类型与 Enum 类型也不能进行比较,即使属性和值一样.
枚举方法 。
枚举中可以定义枚举类自身特有的方法,也可以复写一些已经在基类中定义好的方法,比如: __init__, __str__, __repr__ , __hash__ ,__format__ 等。举个例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
from
enum
import
Enum
class
Mood(Enum):
FUNKY
=
(
1
,
"hello"
)
HAPPY
=
(
3
,
"world"
)
def
describe(
self
):
return
self
.name,
self
.value
def
__init__(
self
, num, nice):
self
.num
=
num
self
.nice
=
nice
def
__str__(
self
):
return
'my custom str! {0}'
.
format
(
self
.value)
@classmethod
def
favorite_mood(
cls
):
return
cls
.HAPPY
@property
def
testValue(
self
):
return
self
.nice
+
':'
+
str
(
self
.num)
|
上面我们定义了一个枚举类,其中 value 是一个枚举类型,我们可以定义 __init__ 方法去对应元组中的值,我们也复写了 __str__ 方法.
打印方法看看效果:
1
2
3
4
|
print
(Mood.favorite_mood())
# my custom str! (3, 'world')
print
(Mood.HAPPY.describe())
# ('HAPPY', (3, 'world'))
print
(
str
(Mood.FUNKY))
# my custom str! (1, 'hello')
print
(Mood.FUNKY.testValue)
# hello:1
|
从输出结果看,我们自定义和复写的方法都已经成功的应用到了 Mood 类中.
枚举继承 。
不同于 java 中的枚举类, python 中的枚举类是可以被继承的,但是被继承的枚举类规定其不能定义任何成员,但可以定义抽象方法。举例如下:
1
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
31
32
|
class
EnumExtend(unittest.TestCase):
def
test_extending(
self
):
class
Shade(Enum):
def
shade(
self
):
print
(
self
.name)
class
Color(Shade):
red
=
1
green
=
2
blue
=
3
with
self
.assertRaises(TypeError):
class
MoreColor(Color):
cyan
=
4
magenta
=
5
yellow
=
6
def
test_extending2(
self
):
class
Shade(Enum):
def
shade(
self
):
return
self
.name
class
Color(Shade):
def
hex
(
self
):
return
'%s nice!'
%
self
.value
class
MoreColor(Color):
cyan
=
4
magenta
=
5
yellow
=
6
self
.assertEqual(MoreColor.magenta.shade(),
'magenta'
)
self
.assertEqual(MoreColor.magenta.
hex
(),
'5 nice!'
)
|
测试用例可以完美运行,我们可以发现:第一个方法中,抛出了 TypeError 的异常;第二个测试方法中,MoreColor 继承了 Color, Color 继承了 Shade, 并且我们可以通过子类调用父类中的方法.
总结 。
本节主要介绍了 enum 模块的基础知识,包含枚举的创建、枚举成员和属性的访问、枚举方法的创建、枚举的继承等。其中新版中的 _ignore_、_order_、_missing_ 等可以学习官网的例子,另外 enum 的子类 IntEnum、IntFlag等也是我们比较常用的枚举基类,本文中简单的介绍了 IntEnum, 而 IntFlag 相比与 IntEnum 多了 &, |, ^, ~ 的操作,其他的子类大家感兴趣也可以了解.
代码地址 。
示例代码:Python-100-days-day036 。
以上就是一文读懂Python 枚举的详细内容,更多关于Python 枚举的资料请关注我其它相关文章! 。
原文链接:http://www.justdopython.com/2019/10/09/python-enum-033/ 。
最后此篇关于一文读懂Python 枚举的文章就讲到这里了,如果你想了解更多关于一文读懂Python 枚举的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我是一名优秀的程序员,十分优秀!