Python 正在为枚举使用_prepare__。。。什么';什么是陷阱?
Python的声明性用法要求提供值,而在枚举的最基本用例中,我们实际上并不关心名称和值。我们只关心哨兵自己。在最近阅读了一篇文章之后,我意识到可以使用enum元类的方法来获得这种声明:Python 正在为枚举使用_prepare__。。。什么';什么是陷阱?,python,enums,metaclass,python-3.6,Python,Enums,Metaclass,Python 3.6,Python的声明性用法要求提供值,而在枚举的最基本用例中,我们实际上并不关心名称和值。我们只关心哨兵自己。在最近阅读了一篇文章之后,我意识到可以使用enum元类的方法来获得这种声明: class Color(Enum): red blue green 而让事情变得如此干涸的实现实际上相当简单: from collections import defaultdict class EnumMeta(type): @classmethod def __pr
class Color(Enum):
red
blue
green
而让事情变得如此干涸的实现实际上相当简单:
from collections import defaultdict
class EnumMeta(type):
@classmethod
def __prepare__(meta, name, bases):
return defaultdict(object)
def __new__(cls, name, bases, classdict):
classdict.default_factory = None
return type.__new__(cls, name, bases, classdict)
class Enum(metaclass=EnumMeta):
pass
在Python 3.6中,提供了帮助解决该问题的接口,但接口仍然很奇怪-需要为每个成员指定auto()
值,并从不同的基继承,从而修复\uu repr\uu
:
class Color(NoValue):
red = auto()
blue = auto()
green = auto()
知道为标准库选择的实现花费了大量的人力和精力,一定有某种原因导致前面演示的声明性枚举的更具Python风格的版本不能正常工作
我的问题是,所提出的方法存在哪些问题和故障模式,以及为什么会反对这种方法(或类似的方法)——Python 3.6中包含了
auto
功能?将defaultdict
作为枚举的名称空间有几个陷阱:
- 除其他枚举成员/方法外,无法访问任何内容
- 输入错误会创建新成员
- 丢失保护窗体
命名空间:\u EnumDict
- 覆盖成员
- 覆盖方法
- 较新的
\u生成
方法
- 这是行不通的
\uuuuuuuuuuuuuuuuuu
不仅可以在名称空间dict上设置属性,名称空间dict本身也可以设置属性,\uEnumdict
可以:\uMember\uNames
,一个应该是成员的所有属性的列表
但是,声明一个没有值的名称的目标并非不可能——1包允许它有一些保护措施:
- 魔法自动行为仅在定义成员时出现(一旦定义了普通方法,它就会关闭)
- 默认情况下,
、property
和classmethod
被排除在外,但可以包括它们和/或排除其他全局名称staticmethod
aenum
例如:
from aenum import AutoEnum
class Color(AutoEnum):
red
green
blue
尽管如此,\uuu repr\uuu
仍然显示创建的值
--
1披露:我是,和图书馆的作者
2NamedConstant
(就像上面说的;),NamedTuple
(基于元类、默认值等),以及一些内置枚举:
-->多个值可以映射到一个名称(而不是别名)多值枚举
-->具有相同值的名称不是别名(想想扑克牌)NoAliasEnum
-->根据定义,成员的顺序是可比较的orderedum
-->不允许使用别名uniquenum
from enum import Enum
class NoValue(Enum):
def __repr__(self):
return '<%s.%s>' % (self.__class__.__name__, self.name)
Color = NoValue('Color', ['red', 'green', 'blue']) # no need for "auto()" calls
但是对于
enum
它们应该被解释为赋值吗?这个用例根本没有被考虑。很有趣,谢谢!我刚刚简单地浏览了一下AutoEnum
的实现,但它很快就深入到了\u generate\u next\u value\u
的内容中。公平地说,元类使用了与我的问题中描述的相同的基本技巧,还是完全不同的实现?@wim:Similar:defaultdict
使用了\uuuu missing\uuu
方法,而\u EnumDict
捕获\uu getitem\uuuuuuuu
查找并从那里处理它。@wim:aenum中的一系列复杂性支持Python 2.x系列。几天前,我打开了Enum
的stdlib版本,感觉就像呼吸了一口新鲜空气!Hm,在文档中没有一个引用到aenum
。对于那些希望获得更神奇的东西的用户来说,这似乎是一个很好的参考。@JimFasarakisHilliard:Python文档没有引用外部项目的习惯(我相信只有几个例外)。也许是维基,虽然…是的,我知道功能界面(我不喜欢它)。。。这就是为什么问题的开头是:“Python枚举的声明性用法…”+1获取相关讨论的链接
class A(object):
a