有没有办法为python枚举指定默认值?

时间:2017-07-02 04:55:40

标签: python enums

鉴于以下枚举:

class MyEnum(IntEnum):

    A = 0
    B = 1
    C = 2

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

my_val = MyEnum()

my_val<MyEnum.A: 0>

这可能吗?我已尝试自定义__new____init____call__,但我无法将其付诸实施。

4 个答案:

答案 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