鉴于以下枚举:
class MyEnum(IntEnum):
A = 0
B = 1
C = 2
如何指定默认值。我希望能够做到:
my_val = MyEnum()
并my_val
为<MyEnum.A: 0>
这可能吗?我已尝试自定义__new__
,__init__
,__call__
,但我无法将其付诸实施。
答案 0 :(得分:5)
MyEnum(..)
由EnumMeta.__call__
处理。您需要覆盖该方法:
from enum import EnumMeta, IntEnum
class DefaultEnumMeta(EnumMeta):
default = object()
def __call__(cls, value=default, *args, **kwargs):
if value is DefaultEnumMeta.default:
# Assume the first enum is default
return next(iter(cls))
return super().__call__(value, *args, **kwargs)
# return super(DefaultEnumMeta, cls).__call__(value, *args, **kwargs) # PY2
class MyEnum(IntEnum, metaclass=DefaultEnumMeta):
# __metaclass__ = DefaultEnumMeta # PY2 with enum34
A = 0
B = 1
C = 2
assert MyEnum() is MyEnum.A
assert MyEnum(0) is MyEnum.A
assert MyEnum(1) is not MyEnum.A
答案 1 :(得分:1)
为什么不使用standard syntax?
my_val = MyEnum.A
如果你真的想这样做,你可能必须编写自己的枚举元覆盖类。您可以在implementation in cpython中看到此示例,以便为枚举的值映射指定一个等于第一个值的默认值。
答案 2 :(得分:1)
如果您不控制Enum
,请执行:
my_val = list(MyEnum)[0]
或者,如果Enum
可能为空:
my_val = len(MyEnum) and list(MyEnum)[0] or None
如果您确实控制了Enum
,则添加get_default
方法:
class MyEnum(Enum):
def get_default(self):
return self.A
或甚至更简单,使default
成为别名:
class MyEnum(Enum):
A = 0
B = 1
C = 2
default = A
您还可以将第一个方法包装到函数中:
def default_member(enum):
return list(enum)[0]
答案 3 :(得分:1)
falsetru's answer是需要解决0个参数大小写的情况。
如果仅在不存在给定值时返回默认值,则可以覆盖Enum类中的_missing_
钩子(自Python 3.6起):
from enum import IntEnum
class MyEnum(IntEnum):
A = 0
B = 1
C = 2
@classmethod
def _missing_(cls, value):
return MyEnum.A
assert MyEnum(0) is MyEnum.A
assert MyEnum(1) is MyEnum.B
assert MyEnum(-1) is MyEnum.A
assert MyEnum(None) is MyEnum.A