考虑下面的枚举:有没有办法指定python枚举的默认值?
class MyEnum(IntEnum):
A = 0
B = 1
C = 2
我如何可以指定一个默认值。我希望能够做到:
my_val = MyEnum()
,并有my_val
是<MyEnum.A: 0>
这可能吗?我试过定制__new__
,__init__
,__call__
但我无法让它工作。
考虑下面的枚举:有没有办法指定python枚举的默认值?
class MyEnum(IntEnum):
A = 0
B = 1
C = 2
我如何可以指定一个默认值。我希望能够做到:
my_val = MyEnum()
,并有my_val
是<MyEnum.A: 0>
这可能吗?我试过定制__new__
,__init__
,__call__
但我无法让它工作。
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
对于这样一个简单的问题看起来像严重的矫枉过正。 –
@EthanFurman,是的。但我无法想出满足MyEnum()是MyEnum.A的解决方案 – falsetru
这是解决这个确切标准的唯一解决方案。 –
为什么不使用standard syntax?
my_val = MyEnum.A
如果你真的想这样做,你可能需要编写自己的枚举元覆盖类。您可以看到implementation in cpython这个例子,这样您就可以为该枚举的值映射分配一个默认值,该值等于该值的第一个值。
如果不控制Enum
S,然后执行:
my_val = list(MyEnum)[0]
,或者,如果Enum
可能是空的:
my_val = len(MyEnum) and list(MyEnum)[0] or None
如果您确实控制了Enum
s,然后添加一个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]
你想'my_val'是枚举值'A'?你不想'my_val'成为'MyEnum'的一个实例吗? –
@ChristianDean我想要做'my_val = MyEnum()'并且结果与'my_val = MyEnum(0)'相同' – Stephen
你想要这样的东西吗? http://ideone.com/mKk5nF或http://ideone.com/mfW9Jr – falsetru