Hep*_*tus 5 python enums python-2.7
我有一个简单的Python2.7枚举:
from enum import Enum
class Label(enum):
RedApple = 1
GreenApple = 2
Run Code Online (Sandbox Code Playgroud)
我希望能够使用不区分大小写的键创建枚举对象:
fruitname = "redapple"
a = Label[fruitname]
Run Code Online (Sandbox Code Playgroud)
我试过创建一个__init__
方法:
def __init__(self, key):
super(Label, self).__init__()
pass # do comparison here
Run Code Online (Sandbox Code Playgroud)
但一直遇到错误:
super(Label, self).__init__()
NameError: global name 'Label' is not defined
Run Code Online (Sandbox Code Playgroud)
我想做一个比较key.lower().strip()
.
这甚至可能吗?
在Python 3.6和1 2(与2.7和3.0+兼容)中添加了一种新方法:2.aenum 2.0
_missing_
在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
Run Code Online (Sandbox Code Playgroud)
在使用中:
>>> Label['redapple']
<Label.RedApple: 1>
Run Code Online (Sandbox Code Playgroud)
如果使用3.6 stdlib卡住(或想要保持兼容),你可以(ab)使用_missing_
但是:
Label('redapple')
(圆形的parens,而不是方括号),和1披露:我是Python stdlibEnum
,enum34
backport和Advanced Enumeration(aenum
) 库的作者.
2 enum34
没有这些改进,因为它只是为bug修复而维护.
3 _missing_value_
是优选的,aenum
因为它更明确地检查它是什么,但它回退到_missing_
与stdlib的兼容性.
4 aenum v2.0.2有一个错误,_missing_
如果_missing_name_
没有被覆盖,则会为值和名称调用- 这在v2.0.3 +中得到修复.
小智 8
枚举缺少函数,可以覆盖该函数以使枚举不区分大小写。 \n根据文档\n https://docs.python.org/3.11/howto/enum.html \n缺少\xe2\x80\x93 使用的查找函数当没有找到值时;可能会被覆盖
\n例子
\nclass Status(enum.Enum):\n @classmethod\n def _missing_(cls, value):\n for member in cls:\n if member.value == value.upper():\n return member\n SUCCESS = \'SUCCESS\'\n FAILURE = \'FAILURE\'\n\nprint(Status(\'success\'))\n
Run Code Online (Sandbox Code Playgroud)\n输出
\nStatus.SUCCESS\n
Run Code Online (Sandbox Code Playgroud)\n
不是 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)
Run Code Online (Sandbox Code Playgroud)
这假定您的枚举都是大写的。使用它非常简单:
class Label(Enum, metaclass=CaseInsensitiveEnumMeta):
REDAPPLE = 1
GREENAPPLE = 2
Run Code Online (Sandbox Code Playgroud)
我不确定Enum
在这种情况下你甚至需要。这里的问题是你的枚举必须全部大写才能工作。如果您想进行真正不敏感的搜索,您必须确保所有的键__members__
都正确地折叠起来。
与此同时,你可以做
>>> Label['GreenApple']
Label.GREENAPPLE
Run Code Online (Sandbox Code Playgroud)