上一篇文章,我写了Pytest插件pytest-order指定用例顺序
我当时就比较好奇它的顺序和英文的对应关系,肯定是写死的,找了下就发现在源码sorter.py中定义了一个dict如下
orders_map = {
"first": 0,
"second": 1,
"third": 2,
"fourth": 3,
"fifth": 4,
"sixth": 5,
"seventh": 6,
"eighth": 7,
"last": -1,
"second_to_last": -2,
"third_to_last": -3,
"fourth_to_last": -4,
"fifth_to_last": -5,
"sixth_to_last": -6,
"seventh_to_last": -7,
"eighth_to_last": -8,
}
于是乎顺道看了下它其他的源代码,在settings这个模块中有如下一段
class Scope(Enum):
CLASS = 1
MODULE = 2
SESSION = 3
class Settings:
"""Holds all configuration settings."""
valid_scopes = {
"class": Scope.CLASS,
"module": Scope.MODULE,
"session": Scope.SESSION,
}
...
之前在python中使用枚举更多是用来遍历容器(确切的说列表,虽说它支持多数sequence)
list1 = [1,3,5,7]
for i,v in enumerate(list1):
print(f'第{i+1}个元素是{v}')
# 输出
第1个元素是1
第2个元素是3
第3个元素是5
第4个元素是7
枚举模块(enum)是Python 3.4添加的功能,什么是枚举(enumeration)呢?根据官方文档:
即枚举代表了一系列互不相同的常量,这一系列常量可以通过identity互相比较,也可以进行迭代。
from enum import Enum
# 比如一个环境的定义
class Env(Enum):
UI = 0
API = 1
PERFORMANCE = 2
COMP = 3
PEP 435中的介绍
The properties of an enumeration are useful for defining an immutable, related set of constant values that may or may not have a semantic meaning.
在Python中,使用枚举的目的主要是方便常量的管理,方便记忆的同时使代码更加简洁易读。
举个例子,在代码中通常使用不同的整数代表一些常量。比如用0代表UI,1代表API等。但是带来的麻烦是:写代码/阅读代码的人极有可能不明白这个0背后的意义。用枚举就可以解决这个问题。
而且注意:枚举的value一旦确定,是不可更改的,这样就保证了常量的安全。
类名.Field.name 访问字段名
类名.Field.value 访问字段值(更常用)
from enum import Enum
# 比如一个环境的定义
class Env(Enum):
UI = 0
API = 1
PERFORMANCE = 2
COMP = 3
# 典型的访问 类名.Field.name
print(Env.COMP.name) # COMP
print(Env.COMP.value) # 3
有点常量的感觉,但这点是非常有优势的
Env.COMP.value = 4
Traceback (most recent call last):
File "D:\enum_test.py", line 14, in <module>
Env.COMP.value = 4
File "D:\Python39\lib\types.py", line 182, in __set__
raise AttributeError("can't set attribute")
AttributeError: can't set attribute
class Config(Enum):
HOST = 'https://www.baidu.com'
DB = '192.168.1.1'
PORT = 3306
USERNAME = 'ADMIN'
PASSWORD = '123456'
print(Config.HOST.value) # https://www.baidu.com
要对enum的item进行唯一性限制可以用该装饰器
from enum import Enum,unique
class Env1(Enum):
MONDAY = 1
FLAG = 1
print(Env1.FLAG.value) # 不加装饰器可以重复
Traceback (most recent call last):
File "D:\enum_test.py", line 10, in <module>
class Env2(Enum):
File "D:\Python39\lib\enum.py", line 1013, in unique
raise ValueError('duplicate values found in %r: %s' %
ValueError: duplicate values found in <enum 'Env2'>: FLAG -> MONDAY
enum还有一些其他的功能,比如
auto:自动产生一些内容
>>> from enum import Enum, auto
>>> class Color(Enum):
... RED = auto()
... BLUE = auto()
... GREEN = auto()
IntEnum继承自int和Enum,它只允许枚举的value为整数型
Flag和Enum的不同在于:
Flag的value只能是整数;
Flag支持位运算符(&与、|或、^异或、~取反)
IntFlag继承自int和Flag,因此int和Flag的特性它都有,即
IntFlag的value只能是整数;
IntFlag支持位运算符(&与、|或、^异或、~取反)
IntFlag还能当成整数用,比如和整数进行运算,索引等等
更多信息可以参考官文:https://docs.python.org/3.9/library/enum.html?highlight=enum#module-enum
深入探讨Python中的并发编程,特别关注多线程和多进程的应用。我们将先从基本概念开始,然后通过详细举例探讨每一种机制,最后分享一些实战经验以及一种优雅的编程技巧。