1. enum枚举

枚举是一组符号名称(枚举成员)的集合,枚举成员应该是唯一的、不可变的。在枚举中,可以对成员进行恒等比较,并且枚举本身是可迭代的。

1.1 创建枚举

可以使用class语法派生Enum并增加描述值的类属性来定义一个新枚举。

import enum

class BugStatus(enum.Enum):

    new = 7
incomplete = 6
invalid = 5
wont_fix = 4
in_progress = 3
fix_committed = 2
fix_released = 1 print('\nMember name: {}'.format(BugStatus.wont_fix.name))
print('Member value: {}'.format(BugStatus.wont_fix.value))

解析这个类时,Enum的成员会被转换为实例。每个实例有一个对应成员名的name属性,另外有一个value属性,对应为类定义中的名所赋的值。

1.2 迭代

迭代处理enum类会产生枚举的各个成员。

import enum

class BugStatus(enum.Enum):

    new = 7
incomplete = 6
invalid = 5
wont_fix = 4
in_progress = 3
fix_committed = 2
fix_released = 1 for status in BugStatus:
print('{:15} = {}'.format(status.name, status.value))

这些成员按它们在类定义中声明的顺序生成。不会用名和值来对它们排序。

1.3 比较Enum

由于枚举成员是无序的,所以它们只支持按同一性和相等性进行比较。

import enum

class BugStatus(enum.Enum):

    new = 7
incomplete = 6
invalid = 5
wont_fix = 4
in_progress = 3
fix_committed = 2
fix_released = 1 actual_state = BugStatus.wont_fix
desired_state = BugStatus.fix_released print('Equality:',
actual_state == desired_state,
actual_state == BugStatus.wont_fix)
print('Identity:',
actual_state is desired_state,
actual_state is BugStatus.wont_fix)
print('Ordered by value:')
try:
print('\n'.join(' ' + s.name for s in sorted(BugStatus)))
except TypeError as err:
print(' Cannot sort: {}'.format(err))

大于或小于比较符会产生TypeError异常。

有些枚举中的成员要表现得更像数字,例如,要支持比价,对于这些枚举要使用IntEnum类。

import enum

class BugStatus(enum.IntEnum):

    new = 7
incomplete = 6
invalid = 5
wont_fix = 4
in_progress = 3
fix_committed = 2
fix_released = 1 print('Ordered by value:')
print('\n'.join(' ' + s.name for s in sorted(BugStatus)))

1.4 唯一枚举值

有相同值的Enum成员会被处理为同一个成员对象的别名引用。别名可以避免Enum的迭代器中出现重复的值。

import enum

class BugStatus(enum.Enum):

    new = 7
incomplete = 6
invalid = 5
wont_fix = 4
in_progress = 3
fix_committed = 2
fix_released = 1 by_design = 4
closed = 1 for status in BugStatus:
print('{:15} = {}'.format(status.name, status.value)) print('\nSame: by_design is wont_fix: ',
BugStatus.by_design is BugStatus.wont_fix)
print('Same: closed is fix_released: ',
BugStatus.closed is BugStatus.fix_released)

由于by_design和closed是其他成员的别名,迭代处理Enum时它们不会单独出现在输出中。一个成员的规范名是与这个值关联的第一个名字。

如果要求所有成员有唯一的值,则要为Enum增加@unique修饰符。

class BugStatus(enum.Enum):

    new = 7
incomplete = 6
invalid = 5
wont_fix = 4
in_progress = 3
fix_committed = 2
fix_released = 1 # This will trigger an error with unique applied.
by_design = 4
closed = 1

解释Enum类时,有重复值的成员会触发一个ValueError异常。

1.5 通过编程创建枚举

有些情况下,通过编程创建枚举会更方便,而不是在类定义中硬编码定义枚举。在这些情况下,Enum还支持向类构造函数传递成员名和值。

import enum

BugStatus = enum.Enum(
value='BugStatus',
names=('fix_released fix_committed in_progress '
'wont_fix invalid incomplete new'),
) print('Member: {}'.format(BugStatus.new)) print('\nAll members:')
for status in BugStatus:
print('{:15} = {}'.format(status.name, status.value))

value参数是枚举名,用于构建成员的表示。names参数会列出枚举的成员。传递单个字符串时,会按空白符和逗号拆分,所得到的token会被用作成员名,这些成员还会自动赋值,从1开始。

要想更多地控制与成员关联的值,可以把names字符串替换为一个由两部分元组构成的序列或者一个将名映射到值的字典。

import enum

BugStatus = enum.Enum(
value='BugStatus',
names=[
('new', 7),
('incomplete', 6),
('invalid', 5),
('wont_fix', 4),
('in_progress', 3),
('fix_committed', 2),
('fix_released', 1),
],
) print('All members:')
for status in BugStatus:
print('{:15} = {}'.format(status.name, status.value))

在这个例子中,指定了一个两部分元组的列表而不是一个只包含成员名的字符串。这样就可以按enum_create.py中定义的同样的顺序利用成员重新构造BugStatus枚举。

1.6 非整数成员值

Enum成员值并不仅限于整数。任何类型的对象都可以与成员关联。如果值是一个元组,那么成员会作为单个参数被传递到__init__()。

import enum

class BugStatus(enum.Enum):

    new = (7, ['incomplete',
'invalid',
'wont_fix',
'in_progress'])
incomplete = (6, ['new', 'wont_fix'])
invalid = (5, ['new'])
wont_fix = (4, ['new'])
in_progress = (3, ['new', 'fix_committed'])
fix_committed = (2, ['in_progress', 'fix_released'])
fix_released = (1, ['new']) def __init__(self, num, transitions):
self.num = num
self.transitions = transitions def can_transition(self, new_state):
return new_state.name in self.transitions print('Name:', BugStatus.in_progress)
print('Value:', BugStatus.in_progress.value)
print('Custom attribute:', BugStatus.in_progress.transitions)
print('Using attribute:',
BugStatus.in_progress.can_transition(BugStatus.new))

在这个例子中,每个成员值分别是一个元组,包括数值ID(如可能存储在一个数据库中的ID)和从当前状态迁移的一个合法变迁列表。

对于更复杂的情况,元组可能变得很难用。因为成员值可以是任意类型的对象,如果对每个enum值都需要跟踪大量单独的属性,那么这些情况下可以使用字典。复杂的值可以直接作为唯一参数传递到__init__()而不是self。

import enum

class BugStatus(enum.Enum):

    new = {
'num': 7,
'transitions': [
'incomplete',
'invalid',
'wont_fix',
'in_progress',
],
}
incomplete = {
'num': 6,
'transitions': ['new', 'wont_fix'],
}
invalid = {
'num': 5,
'transitions': ['new'],
}
wont_fix = {
'num': 4,
'transitions': ['new'],
}
in_progress = {
'num': 3,
'transitions': ['new', 'fix_committed'],
}
fix_committed = {
'num': 2,
'transitions': ['in_progress', 'fix_released'],
}
fix_released = {
'num': 1,
'transitions': ['new'],
} def __init__(self, vals):
self.num = vals['num']
self.transitions = vals['transitions'] def can_transition(self, new_state):
return new_state.name in self.transitions print('Name:', BugStatus.in_progress)
print('Value:', BugStatus.in_progress.value)
print('Custom attribute:', BugStatus.in_progress.transitions)
print('Using attribute:',
BugStatus.in_progress.can_transition(BugStatus.new))

这个例子描述了与前例相同的数据,不过使用的是字典而非元组。

Python3标准库:enum枚举的更多相关文章

  1. 8.Python3标准库--数据持久存储与交换

    ''' 持久存储数据以便长期使用包括两个方面:在对象的内存中表示和存储格式之间来回转换数据,以及处理转换后数据的存储区. 标准库包含很多模块可以处理不同情况下的这两个方面 有两个模块可以将对象转换为一 ...

  2. 7.Python3标准库--文件系统

    ''' Python的标准库中包含大量工具,可以处理文件系统中的文件,构造和解析文件名,还可以检查文件内容. 处理文件的第一步是要确定处理的文件的名字.Python将文件名表示为简单的字符串,另外还提 ...

  3. 1.Python3标准库--前戏

    Python有一个很大的优势便是在于其拥有丰富的第三方库,可以解决很多很多问题.其实Python的标准库也是非常丰富的,今后我将介绍一下Python的标准库. 这个教程使用的书籍就叫做<Pyth ...

  4. Python3 标准库

    Python3标准库 更详尽:http://blog.csdn.net/jurbo/article/details/52334345 文本 string:通用字符串操作 re:正则表达式操作 diff ...

  5. python023 Python3 标准库概览

    Python3 标准库概览 操作系统接口 os模块提供了不少与操作系统相关联的函数. >>> import os >>> os.getcwd() # 返回当前的工作 ...

  6. 比较两个文件的异同Python3 标准库difflib 实现

    比较两个文件的异同Python3 标准库difflib 实现 对于要比较两个文件特别是配置文件的差异,这种需求很常见,如果用眼睛看,真是眼睛疼. 可以使用linux命令行工具diff a_file b ...

  7. python3标准库总结

    Python3标准库 操作系统接口 os模块提供了不少与操作系统相关联的函数. ? 1 2 3 4 5 6 >>> import os >>> os.getcwd( ...

  8. 3.Python3标准库--数据结构

    (一)enum:枚举类型 import enum ''' enum模块定义了一个提供迭代和比较功能的枚举类型.可以用这个为值创建明确定义的符号,而不是使用字面量整数或字符串 ''' 1.创建枚举 im ...

  9. 9.Python3标准库--数据压缩与归档

    ''' 尽管现代计算机系统的存储能力日益增长,但生成数据的增长是永无休止的. 无损(lossless)压缩算法以压缩或解压缩数据花费的时间来换取存储数据所需要的空间,以弥补存储能力的不足. Pytho ...

随机推荐

  1. STP 生成树协议 RSTP 快速生成树

    STP(Spanning Tree Protocol)是生成树协议的英文缩写 该协议可应用于在网络中建立树形拓扑,消除网络中的环路,并且可以通过一定的方法实现路径冗余,但不是一定可以实现路径冗余.生成 ...

  2. [Python]执行Linux命令

    使用subprocess模块 import subprocess # 防火墙服务存在关闭状态 child1 = subprocess.Popen(["systemctl status fir ...

  3. 怎么用IDEA快速查看类图关系

    做Java开发的,现在普遍都用上idea了.可以说,idea是当之无愧的Java开发神器.如果,你现在还没用idea,那肯定是你还没有感受过它的强大. 好了,话不多说,今天的主题主要是教大家怎么通过i ...

  4. 浅谈 k8s ingress controller 选型

    大家好,先简单自我介绍下,我叫厉辉,来自腾讯云.业余时间比较喜欢开源,现在是Apache APISIX PPMC.今天我来简单给大家介绍下 K8S Ingress 控制器的选型经验,今天我讲的这些内容 ...

  5. Redis 为什么这么快?

    1. 纯内存操作,肯定快 数据存储在内存中,读取的时候不需要进行磁盘的 IO 2. 单线程,无锁竞争损耗 单线程保证了系统没有线程的上下文切换 使用单线程,可以避免不必要的上下文切换和竞争条件,没有多 ...

  6. Ubuntu 1910安装Openshift 4.0单机版 (CRC)

    Openshift默认可以在CentOS等RHEL系的发行版上安装. 本文转述一下如何在Ubuntu 1910上安装Openshift4.0单机版(CRC). 原文请参考:  https://gith ...

  7. python文件操作汇总day7

    Python处理文件 文件操作分为读.写.修改,我们先从读开始学习 读文件 示例1: f = open(file='D:/工作日常/兼职白领学生空姐模特护士联系方式.txt',mode='r',enc ...

  8. 【Git】git使用 - 各种常用场景命令解决

    (多看git中的各种帮助-h/--help,可能有你想要的命令) 1.分支的创建和切换 创建 >>>> git branch branchName 切换分支 >>& ...

  9. memcached与redis比较

    1- memcached介绍 Memcached是一个自由开源的,高性能,分布式内存对象缓存系统. Memcached是以LiveJournal旗下Danga Interactive公司的Brad F ...

  10. SpringBoot从1.5.1→2.2.4项目加包扫雷三:org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter已过时

    @Configuration@Slf4j@PropertySource({"classpath:/config.properties"})public class MyWebApp ...