我有一个简单的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()
进行比较
这甚至可能吗?
答案 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')
而不是(圆形的方括号,而不是方括号), 1 披露:我是Python stdlib Enum
,enum34
backport和Advanced 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'))
输出
状态.成功