Following system colour scheme - Python 增强提案 Selected dark colour scheme - Python 增强提案 Selected light colour scheme - Python 增强提案

Python 增强提案

PEP 354 – Python 中的枚举

作者:
Ben Finney <ben+python at benfinney.id.au>
状态:
已取代
类型:
标准跟踪
创建:
2005年12月20日
Python 版本:
2.6
历史记录:
2005年12月20日
被取代:
435

内容目录

拒绝通知

此 PEP 已被拒绝。它不能很好地融入任何现有的模块(如 collections),并且 Python 标准库避免在它们自己的模块中包含大量单独的数据结构。此外,此 PEP 没有引起广泛的兴趣。对于需要枚举的人,有一些食谱和 PyPI 包可以满足这些需求。

注意:此 PEP 已被 PEP 435取代,该 PEP 已于 2013 年 5 月被接受。

摘要

此 PEP 指定了 Python 的枚举数据类型。

枚举是一组排他的符号名称,绑定到任意唯一的数值。枚举中的值可以被迭代和比较,但这些值与枚举之外的值没有内在关系。

动机

枚举的属性对于定义一组不可变的相关常量值非常有用,这些值具有定义的序列但没有内在的语义含义。经典的例子是一周中的几天(星期日到星期六)和学校评估等级(“A”到“D”以及“F”)。其他示例包括错误状态值和定义过程中的状态。

可以简单地定义某个其他基本类型(如 intstr)的值序列来表示离散的任意值。但是,枚举确保这些值与任何其他值不同,并且没有定义对这些值进行无意义的操作(“星期三乘以二”)。

规范

枚举类型由类型构造函数的一系列参数创建

>>> Weekdays = enum('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat')
>>> Grades = enum('A', 'B', 'C', 'D', 'F')

没有值的枚举毫无意义。如果构造函数在没有值参数的情况下被调用,则会引发 EnumEmptyError 异常。

这些值绑定到新枚举对象的属性

>>> today = Weekdays.mon

这些值可以进行比较

>>> if today == Weekdays.fri:
...     print "Get ready for the weekend"

枚举中的值不能有意义地进行比较,除非与来自相同枚举的值进行比较。当枚举中的值与任何不来自相同枚举的值或不同类型的值进行比较时,比较操作函数返回 NotImplemented [1]

>>> gym_night = Weekdays.wed
>>> gym_night.__cmp__(Weekdays.mon)
1
>>> gym_night.__cmp__(Weekdays.wed)
0
>>> gym_night.__cmp__(Weekdays.fri)
-1
>>> gym_night.__cmp__(23)
NotImplemented
>>> gym_night.__cmp__("wed")
NotImplemented
>>> gym_night.__cmp__(Grades.B)
NotImplemented

这允许操作成功,并计算为布尔值

>>> gym_night = Weekdays.wed
>>> gym_night < Weekdays.mon
False
>>> gym_night < Weekdays.wed
False
>>> gym_night < Weekdays.fri
True
>>> gym_night < 23
False
>>> gym_night > 23
True
>>> gym_night > "wed"
True
>>> gym_night > Grades.B
True

将枚举中的值强制转换为 str 会导致在构造枚举时为该值指定的字符串

>>> gym_night = Weekdays.wed
>>> str(gym_night)
'wed'

枚举中每个值的序列索引通过该值的 index 属性以整数形式导出

>>> gym_night = Weekdays.wed
>>> gym_night.index
3

可以迭代枚举,以创建枚举时指定的序列返回其值

>>> print [str(day) for day in Weekdays]
['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']

枚举中的值是可散列的,并且可以用作字典键

>>> plans = {}
>>> plans[Weekdays.sat] = "Feed the horse"

枚举的正常用法是为数据类型提供一组可能的值,然后可以使用这些值来映射到有关这些值的其他信息。

>>> for report_grade in Grades:
...     report_students[report_grade] = \
...         [s for s in students if students.grade == report_grade]

基本原理 - 考虑的其他设计

全部在一个类中

某些实现将枚举及其所有值都作为单个对象或类的属性。

此 PEP 指定了一种设计,其中枚举是一个容器,而值是简单的可比较项。人们认为,尝试将枚举的所有属性都放在一个类中会使设计复杂化,而没有明显的益处。

用于创建枚举类的元类

此 PEP 中指定的枚举是 enum 类型的实例。一些替代设计将每个枚举实现为其自己的类,以及一个元类来定义所有枚举的公共属性。

拥有每个枚举的类(而不是实例)的一个动机是允许枚举的子类,扩展和更改现有的枚举。但是,类意味着将创建该类的实例;很难想象拥有“一周中的几天”类的单独实例意味着什么,其中每个实例都包含所有日期。这通常会导致每个类都遵循单例模式,从而进一步使设计复杂化。

相反,此 PEP 指定的枚举预计不会被扩展或修改。当然,可以从现有枚举的字符串值创建一个新的枚举,或者如果需要,甚至可以对 enum 类型进行子类化。

隐藏枚举值的属性

以前的设计使枚举值尽可能地隐藏其实现,甚至不导出字符串键和序列索引。

此 PEP 中的设计承认程序通常会发现知道枚举值的枚举类型、序列索引和为该值指定的字符串键很方便。这些由枚举值作为属性导出。

实现

此设计部分基于 Python Cookbook 中的一个食谱 [2]

PyPI 包 enum [3] 提供了此 PEP 中描述的数据类型的 Python 实现。

参考文献和脚注


来源: https://github.com/python/peps/blob/main/peps/pep-0354.rst

上次修改时间: 2023-09-09 17:39:29 GMT