Python枚举:不区分大小写的构造函数

时间:2017-03-07 21:23:50

标签: python-2.7 enums

我有一个简单的Python2.7枚举:

from enum import Enum
class Label(enum):
    RedApple = 1
    GreenApple = 2

我希望能够使用不区分大小写的键创建枚举对象:

fruitname = "redapple"
a = Label[fruitname]

我尝试创建__init__方法:

def __init__(self, key):
    super(Label, self).__init__()
    pass # do comparison here

但仍然遇到错误:

super(Label, self).__init__()
NameError: global name 'Label' is not defined

我想对key.lower().strip()进行比较 这甚至可能吗?

3 个答案:

答案 0 :(得分:5)

在Python 3.6和aenum 2.0 1 2 (与2.7和3.0+兼容)中添加了一种新方法:_missing_ 2

在引发ValueError之前调用此方法,以使自定义代码有机会尝试按值查找枚举成员。不幸的是,这使得它不适合您的用例 - 按名称查找。

幸运的是,aenum有额外的选项来定义_missing_name_方法 3 ,当名称查找失败时将调用该方法。

上面的代码应如下所示:

from aenum import Enum

class Label(Enum):

    RedApple = 1
    GreenApple = 2

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

并在使用中:

>>> Label['redapple']
<Label.RedApple: 1>

如果使用3.6 stdlib(或想要保持兼容),你可以(ab)使用_missing_但是:

  • 你必须做Label('redapple')而不是(圆形的方括号,而不是方括号),
  • 你将反对enum的设计('redapple'是名字,而不是价值)

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

2 enum34没有这些改进,因为它只是针对错误修复进行维护。

3 _missing_value_aenum中是首选,因为它更明确地检查它是什么,但为了与stdlib兼容,它回退到_missing_

4 aenum v2.0.2有一个错误,如果_missing_未被覆盖,则会为值和名称调用_missing_name_ - 这在v2.0.3中已得到修复+。

答案 1 :(得分:0)

不能100%地确定它可以在Python 2.7中使用,但是我想出了一种简单的方法来使其完全符合Python 3.6+的要求。

这个想法是由类使用方括号查找名称,这意味着它使用了元类中的__getitem__。因此,您可以创建一个实现不区分大小写搜索的简单元类。由于它将扩展现有的EnumMeta,因此它将与现有的枚举完全兼容:

class CaseInsensitiveEnumMeta(EnumMeta):
    def __getitem__(self, item):
        if isinstance(item, str):
            item = item.upper()
        return super().__getitem__(item)

这以您的枚举全部为大写为前提。使用它非常简单:

class Label(Enum, metaclass=CaseInsensitiveEnumMeta):
    REDAPPPE = 1
    GREENAPPLE = 2

在这种情况下,我不确定您甚至不需要Enum。这里要注意的是,您的枚举必须全部大写才能起作用。如果要进行真正不敏感的搜索,则必须确保__members__中的所有键都正确地用大小写折叠。

在此期间,您可以

>>> Label['GreenApple']
Label.GREENAPPLE

答案 2 :(得分:0)

enum 具有 missing 函数,可以覆盖该函数以使枚举不区分大小写。 根据文档 https://docs.python.org/3.11/howto/enum.html missing - 找不到值时使用的查找函数;可能会被覆盖

示例

class Status(enum.Enum):
   @classmethod
   def _missing_(cls, value):
      for member in cls:
         if member.value == value.upper():
            return member
   SUCCESS = 'SUCCESS'
   FAILURE = 'FAILURE'

print(Status('success'))

输出

状态.成功