我想简化以下类,这样我就不需要为每个元素键入值,而是使用枚举成员的名称。这类似于文档中的AutoNumber example。
class Screen(Enum):
MAIN = 'main'
OPTIONS = 'options'
GAME = 'game'
SCORE = 'score'
而不是上述内容,我想做以下事情,以便例如Screen.MAIN
是'main'
:
class Screen(AutoNameValueEnum):
MAIN = ()
OPTIONS = ()
GAME = ()
SCORE = ()
我尝试修改链接的示例,但我无法弄清楚如何获取枚举成员的名称。
答案 0 :(得分:3)
在Enum
中,成员也是Enum
自己。文档中的示例使用成员的__new__
方法来分配值。您不能使用该方法,因为新成员不知道如何在其拥有的类中调用它。而是使用初始化程序。这是一个例子:
>>> class AutoNameValueEnum(enum.Enum):
... def __init__(self):
... self._value_ = self._name_.lower()
...
>>> class Color(AutoNameValueEnum):
... RED = ()
...
>>> Color.RED
<Color.RED: 'red'>
<强>更新强>
请注意,使用此解决方案,不再可以进行值查找。这是因为枚举元类在调用初始值设定项之前存储了值。这将有效地阻止你腌制你的枚举,也可能会破坏其他地方的东西。另一种方法(它对于类似的字符串,即a is "foo"
,对于值,而不是其他任何东西)的等价性,是对值使用不可用类型。然后,枚举类将执行线性搜索,而不是尝试通过映射查找值的键。
class UnhashableString(str):
def __hash__(self):
raise TypeError
class AutoNameValueEnum(enum.Enum):
def __init__(self):
self._value_ = UnhashableString(self._name_.lower())
class Color(AutoNameValueEnum):
RED = ()
此备选方案的更新示例。总而言之,我认为使用功能界面suggested here是最干净的解决方案,因为您可以确保在使用它时没有任何中断。
答案 1 :(得分:3)
<强>更新强>
Python 3.6和aenum 2.0
有一个新方法可以被覆盖,以允许枚举成员的自定义值使这个过程变得非常简单:
def _generate_next_value_(name, start, count, last_values):
return name
name
是会员的名称start
是枚举的起始值(默认为1
)count
是目前为止的成员数last_values
是目前为止的成员值列表使用class
方法*无法实现此目的,但您可以使用Functional API:
Color = enum.Enum(
'Color',
((name, name.lower()) for name in 'BLACK RED GREEN BLUE'.split()),
)
*好的,像Python中的大多数事情一样,如果你努力尝试就可以,但为什么要去做所有额外的工作呢?