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. 我国自主研发的先进辅助驾驶系统(ADAS)控制器产品实现量产配套

    来源: http://www.most.gov.cn/kjbgz/201710/t20171023_135606.htm 感谢对我们ADAS团队的肯定!

  2. 【学习笔记】:JavaScript中的BOM对象

    JavaScript中的BOM对象 BOM(Browser Object Model):浏览器对象模型. BOM可用于对浏览器窗口进行访问,但BOM没有相关的标准,所以根据浏览器的不同,其中定义的对象 ...

  3. pikachu-越权漏洞(Over Permission)

    一.越权漏洞概述 1.1 概述     由于没有用户权限进行严格的判断,导致低权限的账户(例如普通用户)可以去完成高权限账户(例如管理员账户)范围内的操作. 1.2 越权漏洞的分类 (1)平行越权   ...

  4. java工作流系统表单自动 获取数据

    关键词:工作流快速开发平台  工作流流设计  业务流程管理   asp.net 开源工作流  bpm工作流系统  java工作流主流框架  自定义工作流引擎 表单设计器  流程设计器 什么是数据自动获 ...

  5. AndroidStudio报错:GradleSyncIssues-Could not install Gradle distribution from...

    场景 在使用Android Studio 新建 App项目后,编译时提示: GradleSyncIssues-Could not install Gradle distribution from... ...

  6. 宿主机休眠后,虚拟机网络ping不通网关

    宿主机  win10 64位 虚拟机软件  vmware 15 虚拟机 centos 7 64位 网络模式:桥接模式 故障起因:  中午去吃饭,为了节省电费,把宿主机 windows 给休眠了 吃完饭 ...

  7. hive中parquet存储格式数据类型timestamp的问题

    当存储格式为parquet 且 字段类型为 timestamp 且 数据用hive执行sql写入. 这样的字段在使用impala读取时会少8小时.建议存储为sequence格式或者将字段类型设置为st ...

  8. 浅谈background的用法

    div css 背景样式background属性 一.语法及参数 1.语法:background : background-color(颜色) || background-image(图片地址) || ...

  9. 利用ARP欺骗进行MITM(中间人攻击)

    ARP欺骗主要骑着信息收集得作用,比如可以利用欺骗获取对方流量,从流量分析你认为重要得信息 0X01  了解ARP Arp协议 ARP(Address Resolution Protocol,地址解析 ...

  10. DNS | named.run文件很大的处理方法

    在查看/var/named/data目录中发现named.run文件260G+ 总用量 267G -rw-r--r-- 1 named named 1.3K 9月 2 21:27 named.run ...