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. ubuntu16.04 自建源

    来自于https://www.cnblogs.com/liangqihui/p/7150066.html APT本地源的搭建(可用于局域网apt-get源搭建或者本地源) 本文档介绍使用apt-mir ...

  2. Quartz.NET - 课程 6: Cron 触发器

    译者注: 目录在这 [译]Quartz.NET 3.x 教程 原文在这 Lesson 6: CronTrigger 如果你需要一个类似日历概念而不是像 SimpleTrigger 那样指定间隔来调度作 ...

  3. bootstrap-daterangepicker

    1,依赖关系 使用之前需要引用bootstrap.css   daterangpicker.css    jquery.js   boostrap.js  moment.js   daterangpi ...

  4. include 和require 区别

    include和require的区别  1.include() 包含文件 2.include_once(filename)如果已经包含,则不再执行include_once 3.requirerequi ...

  5. 聊聊spring之贯穿全局的重要对象BeanDefinition

    BeanDefinition 在 spring 中贯穿始终,spring 要根据 BeanDefinition 对象来实 例化 bean,只要把解析的标签,扫描的注解类封装成 BeanDefiniti ...

  6. springboot容器加载完毕执行某一个方法

    问题: 最近做项目(项目使用的是springboot)的时候,数据库有一个配置参数表,每次都要查询数据库去做数据转换,这样每次查询数据库感觉不太友好,后来写了一个方法项目启动完成后立即执行此方法,将配 ...

  7. OSI七层协议大白话解读

    参考链接:https://www.cnblogs.com/zx125/p/11295985.html 国际标准化组织(ISO)制定了osi七层模型,iso规定了各种各样的协议,并且分了7层 应用层 应 ...

  8. 实验一Git代码版本管理

    GIT代码版本管理 实验目的: 1)了解分布式分布式版本控制系统的核心机理: 2) 熟练掌握git的基本指令和分支管理指令: 实验内容: 1)安装git 2)初始配置git ,git init git ...

  9. SpringBoot 教程之 profile 的应用

    目录   区分环境的配置  区分环境的代码  激活 profile  示例源码  参考资料 一个应用为了在不同的环境下工作,常常会有不同的配置,代码逻辑处理.Spring Boot 对此提供了简便的支 ...

  10. .net mvc 自定义错误页面

    1.Global.asax.cs中,加入如下代码 protected void Application_Error(Object sender, EventArgs e) { Exception ex ...