理解枚举替代实现的缺陷

允我心安 提交于 2019-11-28 08:11:27

Python3.4以前并不提供枚举类型,于是人们利用Python的动态性这个特征,想出了枚举的各种替代实现方式。

  • 使用类属性
class Seasons:
    Spring, Summer, Autumn, Winter = range(4)


print(Seasons.Summer)   # 1
  • 借助函数
def enum(*args, **kwargs):
    return type("Enum", (object,),
                dict(zip(args, range(len(args))), **kwargs))


Seasons = enum("Spring", "Summer", "Autumn", "Winter")
print(Seasons.Summer)   # 1
  • 使用collections.namedtuple
from collections import namedtuple

Seasons = namedtuple('Seasons', 'Spring Summer Autumn Winter')._make(range(4))

print(Seasons.Summer)   # 1

显然,这些替代实现有其不合理的地方。

  • 允许枚举值重复

  • 支持无意义的操作

实际上Python2.7以后的版本还有另外一种替代选择——使用第三方模块flufl.enum,它包含两种枚举类:一种是Enum,只要保证枚举值唯一即可,对值的类型没限制;还有一种是IntEnum,其枚举值为int型。

from flufl.enum import Enum


class Seasons(Enum):
    Spring = 1
    Summer = 2
    Autumn = 3
    Winter = 4


Season = Enum('Seasons', 'Spring Summer Autumn Winter')

# flufl.enum不支持枚举元素的比较
print(repr(Season.Autumn))  # <EnumValue: Seasons.Autumn [value=3]>

# 可以直接使用value属性获取枚举元素的值
print(Season.Autumn.value)  # 3

Python3.4中根据PEP435的建议加入了枚举Enum,其实现主要参考实现flufl.enum,但两者之间还是存在一些差别,如flufl.enum允许枚举继承,而Enum仅在父类没有任何枚举成员的时候才允许继承等。

(最近更新:2019年05月20日)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!