我有一个枚举,当其中不存在成员时,我希望返回默认成员。例如:
class MyEnum(enum.Enum):
A = 12
B = 24
CUSTOM = 1
print(MyEnum.UNKNOWN) # Should print MyEnum.CUSTOM
我知道我可以像这样使用元类:
class MyMeta(enum.EnumMeta):
def __getitem__(cls, name):
try:
return super().__getitem__(name)
except KeyError as error:
return cls.CUSTOM
class MyEnum(enum.Enum,metaclass=MyMeta):
...
但这似乎只有在我使用
MyEnum['UNKNOWN']
访问枚举时才有效。当成员不存在时,是否有一种方法可以涵盖访问枚举成员的两种方法?
将
__getattr__
的定义添加到元类:
class MyMeta(enum.EnumMeta):
def __getitem__(cls, name):
try:
return super().__getitem__(name)
except KeyError as error:
return cls.CUSTOM
def __getattr__(cls, name):
try:
return super().__getattr__(name)
except AttributeError as error:
return cls.CUSTOM
然后,你的代码将输出:
MyEnum.CUSTOM
编译@BrokenBenchmark的答案,和这个答案,以及一些知识,让我们将默认枚举成员设置为参数:
class EnumWithDefaultMeta(enum.EnumMeta):
@classmethod
def __prepare__(metacls, name, bases, **kwargs):
return super().__prepare__(name, bases)
def __new__(metacls, name, bases, namespace, **kwargs):
newclass = super().__new__(metacls, name, bases, namespace)
newclass._missing_ = classmethod(metacls._missing_)
return newclass
def __init__(cls, name, bases, namespace, default='UNKNOWN'):
cls.default = default
super().__init__(name, bases, namespace)
def __getitem__(cls, name):
try:
return super().__getitem__(name)
except KeyError:
return super().__getitem__(cls.default)
def __getattr__(cls, name):
try:
# noinspection PyUnresolvedReferences
return super().__getattr__(name)
except AttributeError:
# noinspection PyUnresolvedReferences
return super().__getattr__(cls.default)
def _missing_(cls, _value):
return super().__getitem__(cls.default)
class MyEnum(enum.Enum, metaclass=EnumWithDefaultMeta, default='CUSTOM'):
A = 12
B = 24
CUSTOM = 1
输出:
MyEnum(123)
>>> <MyEnum.CUSTOM: 1>
MyEnum.Test
>>> <MyEnum.CUSTOM: 1>
MyEnum['Test']
>>> <MyEnum.CUSTOM: 1>