我在__getitem__
的自定义子类上重新定义Enum
时遇到了一些麻烦。我的__getitem__
没有被调用。我想它与Enum
的元类有关,但我不确定是什么和为什么。
最小工作示例(Python 3.4):
from enum import Enum, unique
@unique
class Test(Enum):
a = "a"
b = "b"
def __getitem__(self, name):
try:
return super().__getitem__(name)
except (TypeError, KeyError) as error:
print("TEST")
if __name__ == "__main__":
Test["a"]
Test["c"]
结果:
$ python test.py
Traceback (most recent call last):
File "test.py", line 18, in <module>
Test["c"]
File "C:\Development\Python\Python34\lib\enum.py", line 258, in __getitem__
return cls._member_map_[name]
KeyError: 'c'
答案 0 :(得分:7)
正如@ shx2指出的那样,你没有调用__getitem__()
子类的Enum
。以下是如何通过子类化Enum
的元类:
from enum import Enum, EnumMeta, unique
class TestEnumMeta(EnumMeta):
def __getitem__(self, name):
try:
return super().__getitem__(name)
except (TypeError, KeyError) as error:
print("TEST")
@unique
class Test(Enum, metaclass=TestEnumMeta):
a = "a"
b = "b"
if __name__ == "__main__":
Test["a"]
Test["c"] --> TEST
答案 1 :(得分:6)
如果您在__getitem__
的实例上使用方括号,则会调用Enum
的覆盖。
像Test["A"]
一样访问它会调用元类的__getitem__
方法。因此,在您的情况下,您需要继承EnumMeta
元类,重写其__getitem__
,然后使用该元类创建自己的枚举类。
您可以查看源代码here。
答案 2 :(得分:0)
这是我从 ts 了解到的在 Python 中使用枚举的答案:
from enum import Enum, EnumMeta, unique
class TestEnumMeta(EnumMeta):
def __getitem__(self, indexOrName):
if isinstance(indexOrName, str):
return super().__getitem__(indexOrName).value
elif isinstance(indexOrName, int) and indexOrName < super().__len__():
return list(self)[indexOrName].name
@unique
class Model(Enum, metaclass=TestEnumMeta):
pass
您现在可以像这样使用它:
Test(Model):
type0=0
type1=1
>>> Test['type0']
0
>>> Test[0]
type0