深入了解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多进程编程下线程之间变量的共享问题
May 05 Python
利用python爬取软考试题之ip自动代理
Mar 28 Python
利用Python批量压缩png方法实例(支持过滤个别文件与文件夹)
Jul 30 Python
Python实现的简单排列组合算法示例
Jul 04 Python
Python两个字典键同值相加的几种方法
Mar 05 Python
python循环嵌套的多种使用方法解析
Nov 29 Python
django数据模型on_delete, db_constraint的使用详解
Dec 24 Python
通过实例解析python描述符原理作用
Jan 22 Python
python画图常规设置方式
Mar 05 Python
python如何从键盘获取输入实例
Jun 18 Python
Pycharm 解决自动格式化冲突的设置操作
Jan 15 Python
Pytorch自定义Dataset和DataLoader去除不存在和空数据的操作
Mar 03 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获取当前url的具体方法全面解析
2013/11/26 PHP
PHP实现货币换算的方法
2014/11/29 PHP
golang 调用 php7详解及实例
2017/01/04 PHP
PHP实现的redis主从数据库状态检测功能示例
2017/07/20 PHP
JQuery 表格操作(交替显示、拖动表格行、选择行等)
2009/07/29 Javascript
js 函数的执行环境和作用域链的深入解析
2009/11/01 Javascript
简单的JavaScript互斥锁分享
2014/02/02 Javascript
Javascript基础教程之if条件语句
2015/01/18 Javascript
JQuery select(下拉框)操作方法汇总
2015/04/15 Javascript
javascript处理a标签超链接默认事件的方法
2015/06/29 Javascript
js HTML5 Ajax实现文件上传进度条功能
2016/02/13 Javascript
xtemplate node.js 的使用方法实例解析
2016/08/22 Javascript
利用HTML5+Socket.io实现摇一摇控制PC端歌曲切换
2017/01/13 Javascript
vue loadmore 组件滑动加载更多源码解析
2017/07/19 Javascript
Vue中计算属性computed的示例解读
2017/07/26 Javascript
vuejs事件中心管理组件间的通信详解
2017/08/09 Javascript
vue中使用ueditor富文本编辑器
2018/02/08 Javascript
mpvue+vuex搭建小程序详细教程(完整步骤)
2018/09/30 Javascript
JQuery 实现文件下载的常用方法分析
2019/10/29 jQuery
javascript绘制简单钟表效果
2020/04/07 Javascript
Vue页面渲染中key的应用实例教程
2021/01/12 Vue.js
[02:57]DOTA2亚洲邀请赛 SECRET战队出场宣传片
2015/02/07 DOTA
python中的列表推导浅析
2014/04/26 Python
python scatter函数用法实例详解
2020/02/11 Python
逼真的HTML5树叶飘落动画
2016/03/01 HTML / CSS
美国名牌手表折扣网站:Jomashop
2020/05/22 全球购物
留学自荐信的技巧
2013/10/17 职场文书
好家长事迹材料
2014/01/23 职场文书
幼儿园亲子活动方案
2014/01/29 职场文书
道德模范先进事迹
2014/02/14 职场文书
环保建议书300字
2014/05/14 职场文书
小学校园文化建设汇报材料
2014/08/19 职场文书
节约每一滴水演讲稿
2014/09/09 职场文书
2015年企业新年寄语
2014/12/08 职场文书
小学家长通知书评语
2014/12/31 职场文书
党校毕业个人总结
2015/02/28 职场文书