All*_*mon 2 python enums class python-3.x
我必须在枚举中创建额外的映射来保存附加信息,例如每个枚举案例的详细描述,但又不会丢失枚举类属性。前任:
class MyEnumBase:
description = {
1: 'Description 1',
2: 'This is anover description',
3: 'la la la',
}
class MyEnum(MyEnumBase, Enum):
First = 1
Second = 2
Third = 3
Run Code Online (Sandbox Code Playgroud)
所以我像这样访问它
MyEnum.description[3] == 'la la la'
:
如何扩展 Enum 类,以便在描述与枚举名称相同的情况下,它会使用字段名称填充此字典?
例如:
class MyAnotherEnum(CustomEnumBase):
aaa = 1
bbb = 2
ccc = 3
Run Code Online (Sandbox Code Playgroud)
这样,就会为由此创建的每个枚举MyAnotherEnum.description[3] == 'ccc'
自动生成属性。description
CustomEnumBase
我试图延长Enum
课程时间,但我尝试过的所有方法都失败了。我在想这样的事情:
class CustomEnumBase:
@property
def names(cls):
return {
id:member.name
for id, member in cls._value2member_map_.items()
}
Run Code Online (Sandbox Code Playgroud)
有 2 个限制:
它应该扩展 python Enum 类,因此在需要 Enum 的地方它的行为正确。有一些第三方代码依赖于此。
它应该保留对描述作为映射的访问,因为该协议已经被预期并在代码库中使用。因此将其更改为MyAnotherEnum.description()[id]
不可行,因为它期望映射(字典),而不是函数。
If you are using Python 3.6+ the stdlib Enum
will do; otherwise, you'll need to use the aenum
1 library. In both cases you'll need a to create your own _generate_next_value_
method:
def _generate_next_value_(name, start, count, last_values):
return start+count, name
Run Code Online (Sandbox Code Playgroud)
and borrow classproperty
from this answer:
class classproperty:
def __init__(self, func):
self._func = func
def __get__(self, obj, owner):
return self._func(owner)
Run Code Online (Sandbox Code Playgroud)
If using aenum
(my favorite), the base class will look like:
from aenum import Enum, auto
class DescriptionEnum(Enum):
_init_ = 'value description'
@staticmethod
def _generate_next_value_(name, start, count, last_values):
return start+count, name
@classproperty
def description(cls):
return {
e.value: e.description
for e in cls
}
print(description)
Run Code Online (Sandbox Code Playgroud)
If using Python 3.6 and the stdlib Enum
the base class will look like:
from enum import Enum, auto
class DescriptionEnum(Enum):
def __new__(cls, value, description):
obj = object.__new__(cls)
obj._value_ = value
obj.description = description
return obj
def _generate_next_value_(name, start, count, last_values):
print('generating value', start+count, name)
return start+count, name
@classproperty
def description(cls):
return {
e.value: e.description
for e in cls
}
Run Code Online (Sandbox Code Playgroud)
The difference between those two base classes is the _init_
line vs. the __new__
method. In both cases, your final class would be:
class MyAnotherEnum(DescriptionEnum):
aaa = auto()
bbb = auto()
ccc = auto()
Run Code Online (Sandbox Code Playgroud)
and in use:
>>> print(list(MyAnotherEnum))
[<MyAnotherEnum.aaa: 1>, <MyAnotherEnum.bbb: 2>, <MyAnotherEnum.ccc: 3>]
>>> print(MyAnotherEnum.bbb)
MyAnotherEnum.bbb
>>> print(MyAnotherEnum.bbb.description)
bbb
>>> print(MyAnotherEnum.description)
{1: 'aaa', 2: 'bbb', 3: 'ccc'}
>>> print(MyAnotherEnum.description[2])
bbb
Run Code Online (Sandbox Code Playgroud)
虽然你的Enum
s 没有,但这个新成员description
为每个成员以及Enum
整个成员都有一个属性。这样做的优点之一是,您可以对名称为描述的枚举和指定描述的枚举使用相同的基类:
class MyNormalEnum(DescriptionEnum):
aaa = 1, 'howdy'
bbb = 2, 'bye'
ccc = 3, 'whatever'
Run Code Online (Sandbox Code Playgroud)
并在使用中:
>>> print(list(MyNormalEnum))
[<MyNormalEnum.aaa: 1>, <MyNormalEnum.bbb: 2>, <MyNormalEnum.ccc: 3>]
>>> print(MyNormalEnum.bbb)
MyNormalEnum.bbb
>>> print(MyNormalEnum.bbb.description)
bye
>>> print(MyNormalEnum.description)
{1: 'howdy', 2: 'bye', 3: 'whatever'}
>>> print(MyNormalEnum.description[2])
bye
Run Code Online (Sandbox Code Playgroud)
1声明:我是Python stdlibEnum
、enum34
backport和Advanced Enumeration ( aenum
)库的作者 。
归档时间: |
|
查看次数: |
1720 次 |
最近记录: |