2017-07-02 65 views
3

考虑下面的枚举:有没有办法指定python枚举的默认值?

class MyEnum(IntEnum): 

    A = 0 
    B = 1 
    C = 2 

我如何可以指定一个默认值。我希望能够做到:

my_val = MyEnum() 

,并有my_val<MyEnum.A: 0>

这可能吗?我试过定制__new__,__init__,__call__但我无法让它工作。

+0

你想'my_val'是枚举值'A'?你不想'my_val'成为'MyEnum'的一个实例吗? –

+0

@ChristianDean我想要做'my_val = MyEnum()'并且结果与'my_val = MyEnum(0)'相同' – Stephen

+2

你想要这样的东西吗? http://ideone.com/mKk5nF或http://ideone.com/mfW9Jr – falsetru

回答

3

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

对于这样一个简单的问题看起来像严重的矫枉过正。 –

+0

@EthanFurman,是的。但我无法想出满足MyEnum()是MyEnum.A的解决方案 – falsetru

+0

这是解决这个确切标准的唯一解决方案。 –

0

为什么不使用standard syntax

my_val = MyEnum.A 

如果你真的想这样做,你可能需要编写自己的枚举元覆盖类。您可以看到implementation in cpython这个例子,这样您就可以为该枚举的值映射分配一个默认值,该值等于该值的第一个值。

+0

我正在做一个元类的代码生成,如果我不必知道任何有关枚举的东西来创建它的一个实例,它会让事情变得更简单一些。 – Stephen

+0

@Stephen但不会做'MyEnum(default_value)'工作?如果您提前没有任何有关枚举的信息,只需从中获取默认值即可。 –

+0

@ChristianDean我希望枚举的作者指定默认值。元类不会提前知道默认是什么。 – Stephen

1

如果不控制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] 
+0

我熟悉Enum API。我可以看到你为什么建议这些,但这实际上并没有回答我的问题吗? – Stephen

+0

@Stephen:falsetru已经回答了你的确切问题。我正在提供其他方法来获得你所说的你需要的(默认成员)。 –

+0

我的不好。当我看到这个时,我以为你已经回答过了。如果您正在寻找将枚举设置为默认值的方法,那么您的建议就是有效的,因为您无需在不带参数的情况下调用Enum类。 – Stephen

相关问题