我已经对此进行了研究并找到了类似的答案,但是在这种情况下它们不起作用,因为auto()
早于__new__
被解析,并且仅当整个值为{{1}时}。
基本上,我想要的是以下内容:
_auto_null
但是,该名称未传递到class MyEnum(str, Enum):
one = '1 data'
two = '2 data'
def __new__(cls, data):
member = str.__new__(cls, <NEED NAME HERE>)
member.data = data
member._value_ = <NEED NAME HERE>
assert MyEnum.one == 'one'
assert MyEnum.one.value == 'one'
assert MyEnum.one.data == '1 data'
,因此__new__
无法填写任何内容。
然后,我尝试以下列方式使用<NEED NAME HERE>
:
auto()
这不起作用,因为class MyEnumBase(Enum):
def _generate_next_value_(name, start, count, last_values):
return name
class MyEnum(str, MyEnumBase):
one = '1 data'
two = '2 data'
def __new__(cls, data):
member = str.__new__(cls, auto())
member.data = data
member._value_ = auto()
assert MyEnum.one == 'one'
assert MyEnum.one.value == 'one'
assert MyEnum.one.data == '1 data'
仅在定义成员时用作唯一值时解析,如auto()
中所示。因此,似乎甚至无法执行one = auto()
,然后在one = auto(), '1 data'
函数中同时使用这两个参数。
__new__
似乎我唯一的选择是对名称进行硬编码:
class MyEnum(str, MyEnumBase):
one = auto(), '1 data'
two = auto(), '2 data'
def __new__(cls, name, data):
member = str.__new__(cls, name)
member.data = data
member._value_ = name
并定义one = 'one', '1 data'
函数以采用两个参数:
__new__
我错过了什么吗?有一个更好的方法吗?构建此信息的更好方法是什么?
答案 0 :(得分:5)
这绝对是高级行为,因此要使用它,您需要使用aenum
1 库。
该代码如下所示:
from aenum import Enum, AutoValue
class MyEnum(str, Enum, settings=AutoValue, init='value data'):
def __new__(cls, name, *args, **kwds):
obj = str.__new__(cls, name)
obj._value_ = name
return obj
def _generate_next_value_(name, start, count, last_values, *args, **kwds):
return (name, ) + args
one = '1 data'
two = '2 data'
init
设置说明应该使用给定值的内容;在这种情况下:
value
data
属性 AutoValue
指示aenum
创建一个值,如果缺少一个值 - 因为每个成员只提供一条信息,而init
表示应该有两个,AutoValue
{1}}将尝试提供缺失的部分。
_generate_next_value_
是(之一)用于执行此操作的机制,在这种情况下会将name
添加到给定的data
,然后将其传递给{{} 1}}。
__new__
使用__new__
作为其值并忽略其余
name
来处理非值项,因此会设置__init__
属性
对于那些仍在使用Python 2.7的人,或者需要他们的代码也适用于2.7以及3.x,上面的类应该是这样的(所有更改都在第一个块中):
data
1 披露:我是Python stdlib Enum
,enum34
backport和Advanced Enumeration (aenum
)图书馆的作者。