用Python自定义枚举

时间:2018-08-28 18:09:33

标签: python enums

我可以轻松地创建一个像这样的类

class MyEnum(enum.Enum):
  BOB = "bob"
  RALPH = "ralph"
  ETC = "etc"

然后我可以通过枚举值分配变量:

a = MyEnum('bob')

但是-我想通过可能是正确值的东西来分配变量。即,我想做

a = MyEnum('bob')
b = MyEnum('Bob')
c = MyEnum('BOB')

并使它们全部起作用,并且都映射到相同的枚举值。

有没有做工厂方法的方法吗?我目前已经定义了一种create方法,因此a = MyEnum.create('Bob')可以工作,但是我希望事情是无缝的。

2 个答案:

答案 0 :(得分:2)

您要查找的东西称为_missing_,在Python3.6及更高版本的stdlib中可用,在2.0及更高版本的aenum 1 中可用。

class MyEnum(Enum):

    BOB = "bob"
    RALPH = "ralph"
    ETC = "etc"

    @classmethod
    def _missing_(cls, value):
        for member in cls:
            if member.value == value.lower():
                return member

如果_missing_无法返回MyEnum成员,则EnumMeta将引发异常(因此_missing_不必担心该部分) 2


1 披露:我是Python stdlib Enumenum34 backportAdvanced Enumeration (aenum)库的作者。

2 谢谢您,Aran-Fey。

答案 1 :(得分:0)

这可以通过对EnumMeta进行子类化来实现,该子类是metaclass,负责定义MyEnum('Bob')所调用的__call__方法。

import enum

class CaseInsensitiveEnum(enum.EnumMeta):
    def __call__(self, string):
        string = string.lower()  # convert the string to lowercase
        return super().__call__(string)

class MyEnum(enum.Enum, metaclass=CaseInsensitiveEnum):
  BOB = "bob"
  RALPH = "ralph"
  ETC = "etc"

(请记住,所有枚举值都必须小写;即BOB = 'Bob'无效。)

演示:

>>> MyEnum('Bob')
<MyEnum.BOB: 'bob'>
>>> MyEnum('Bob') is MyEnum.BOB
True