深入了解Python枚举类型的相关知识


Posted in Python onJuly 09, 2019

枚举类型可以看作是一种标签或是一系列常量的集合,通常用于表示某些特定的有限集合,例如星期、月份、状态等。

Python 的原生类型(Built-in types)里并没有专门的枚举类型,但是我们可以通过很多方法来实现它,例如字典、类等:

MiracleLove = {'MON': '林志玲', 'TUS': '陈意涵', 'WEN': '张柏芝', 'THU': '辛芷蕾', 'FRI': '周冬雨'}

class MiracleLove:
  MON = '林志玲'
  TUS = '陈意涵'
  WEN = '张柏芝'
  THU = '辛芷蕾'
  FRI = '周冬雨'

上面两种方法可以看做是简单的枚举类型的实现。

如果只在局部范围内用到了这样的枚举变量是没有问题的。

但问题在于它们都是可变的(mutable),也就是说可以在其它地方被修改从而影响其正常使用:

MiracleLove['MON'] = MiracleLove['FRI']
print(MiracleLove)

通过类定义的枚举甚至可以实例化,变得不伦不类:

ml = MiracleLove()
print(ml.MON)

MiracleLove.MON = 2
print(ml.MON)

当然也可以使用不可变类型(immutable),例如元组,但是这样就失去了枚举类型的本意,将标签退化为无意义的变量:

MiracleLove = ('R', 'G', 'B')
print(MiracleLove[0], MiracleLove[1], MiracleLove[2])

为了提供更好的解决方案,Python 通过 PEP 435 在 3.4 版本中添加了 enum 标准库,3.4 之前的版本也可以通过 pip install enum 下载兼容支持的库。

enum 提供了 Enum/IntEnum/unique 三个工具,用法也非常简单,可以通过继承 Enum/IntEnum 定义枚举类型,其中 IntEnum 限定枚举成员必须为(或可以转化为)整数类型,而 unique 方法可以作为修饰器限定枚举成员的值不可重复:

from enum import Enum, IntEnum, unique

try:
  @unique
  class MiracleLove(Enum):
    MON = '林志玲'
    TUS = '陈意涵'
    WEN = '张柏芝'
    THU = '辛芷蕾'
    FRI = '周冬雨'
except ValueError as e:
  print(e)
  
# duplicate values found in <enum 'MiracleLove'>: FRI -> MON
try:
  class MiracleLove(IntEnum):
    MON = 1
    TUS = 2
    WEN = 3
    THU = 4
    FRI = '周冬雨'
except ValueError as e:
  print(e)

# invalid literal for int() with base 10: '周冬雨'

更有趣的是 Enum 的成员均为单例(Singleton),并且不可实例化,不可更改:

class MiracleLove(Enum):
  MON = '林志玲'
  TUS = '陈意涵'
  WEN = '张柏芝'
  THU = '辛芷蕾'
  FRI = '周冬雨'

try:
  MiracleLove.MON = 2
except AttributeError as e:
  print(e)

# Cannot reassign members.

虽然不可实例化,但可以将枚举成员赋值给变量:

mon = MiracleLove(0)
tus = MiracleLove(1)
wen = MiracleLove(2)
print(mon, tus, wen)

# MiracleLove.MON 
# MiracleLove.TUS 
# MiracleLove.WEN

也可以进行比较判断:

print(mon is MiracleLove.MON)
print(mon == MiracleLove.MON)
print(mon is tus)
print(wen != MiracleLove.TUS)
print(mon == 0) # 不等于任何非本枚举类的值

# True
# True
# False
# True
# False

最后一点,由于枚举成员本身也是枚举类型,因此也可以通过枚举成员找到其它成员:

print(mon.TUS)
print(mon.TUS.WEN.MON)

# MiracleLove.TUS
# MiracleLove.MON

但是要谨慎使用这一特性,因为可能与成员原有的命名空间中的名称相冲突:

print(mon.name, ':', mon.value)
class Attr(Enum):
  name = 'NAME'
  value = 'VALUE'

print(Attr.name.value, Attr.value.name)

# R : 0
# NAME value

总结:

enum 模块的用法很简单,功能也很明确,但是其实现方式却非常值得学习。如果你想更深入了解更多 Python 中关于 Class 和 Metaclass 的黑魔法,又不知道如何入手,那么不妨阅读一下 enum 的源码。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python在多玩图片上下载妹子图的实现代码
Aug 13 Python
python人人网登录应用实例
Sep 26 Python
Python实现从URL地址提取文件名的方法
May 15 Python
Python的Flask框架中使用Flask-SQLAlchemy管理数据库的教程
Jun 14 Python
Python多进程multiprocessing.Pool类详解
Apr 27 Python
Pandas 数据处理,数据清洗详解
Jul 10 Python
详解基于django实现的webssh简单例子
Jul 17 Python
利用pandas读取中文数据集的方法
Jul 25 Python
对python读取CT医学图像的实例详解
Jan 24 Python
浅谈python3.6的tkinter运行问题
Feb 22 Python
详解Python3序列赋值、序列解包
May 14 Python
Python循环实现n的全排列功能
Sep 16 Python
Python 的AES加密与解密实现
Jul 09 #Python
python+numpy按行求一个二维数组的最大值方法
Jul 09 #Python
使用Python轻松完成垃圾分类(基于图像识别)
Jul 09 #Python
Python分析彩票记录并预测中奖号码过程详解
Jul 09 #Python
python求最大值,不使用内置函数的实现方法
Jul 09 #Python
pandas的连接函数concat()函数的具体使用方法
Jul 09 #Python
python爬虫的一个常见简单js反爬详解
Jul 09 #Python
You might like
php返回字符串中所有单词的方法
2015/03/09 PHP
PHP编程计算日期间隔天数的方法
2017/04/26 PHP
Laravel5.1 框架路由基础详解
2020/01/04 PHP
jQuery图片预加载 等比缩放实现代码
2011/10/04 Javascript
基于jQuery判断两个元素是否有重叠部分的代码
2012/07/25 Javascript
JavaScript中的数组操作介绍
2014/12/30 Javascript
jquery实现增加删除行的方法
2015/02/03 Javascript
CSS3 media queries结合jQuery实现响应式导航
2016/09/30 Javascript
微信小程序实战之轮播图(3)
2017/04/17 Javascript
javascript 产生随机数的几种方法总结
2017/09/26 Javascript
React Native 截屏组件的示例代码
2017/12/06 Javascript
vue-infinite-loading2.0 中文文档详解
2018/04/08 Javascript
详解如何使用babel进行es6文件的编译
2018/05/29 Javascript
解决vue请求接口第一次成功,第二次失败问题
2020/09/08 Javascript
vuecli项目构建SSR服务端渲染的实现
2020/10/30 Javascript
python处理圆角图片、圆形图片的例子
2014/04/25 Python
浅谈python中requests模块导入的问题
2018/05/18 Python
selenium + python 获取table数据的示例讲解
2018/10/13 Python
Python实现字典排序、按照list中字典的某个key排序的方法示例
2018/12/18 Python
对Python3.x版本print函数左右对齐详解
2018/12/22 Python
快速查找Python安装路径方法
2020/02/06 Python
Python 如何对文件目录操作
2020/07/10 Python
html5中的一些标签学习(心得)
2016/10/18 HTML / CSS
伦敦鲜花递送:Flower Station
2021/02/03 全球购物
什么样的创业计划书可行性高?
2014/02/01 职场文书
公司总经理岗位职责
2014/03/15 职场文书
成绩单公证书
2014/04/10 职场文书
师德演讲稿范文
2014/05/06 职场文书
条幅标语大全
2014/06/20 职场文书
护林防火标语
2014/06/27 职场文书
高中学生会竞选演讲稿
2014/08/25 职场文书
捐书倡议书
2014/08/29 职场文书
2014财务年终工作总结
2014/12/08 职场文书
《刷子李》教学反思
2016/02/20 职场文书
python编写五子棋游戏
2021/05/25 Python
解决xampp安装后Apache无法启动
2022/03/21 Servers