如何重写list(MyEnum)默认行为以获取所有枚举成员?
为什么重写Enum的__iter__方法不生效?如何让list(MyEnum)返回所有成员?
问题原因
Python的Enum类的迭代行为由它的元类EnumMeta控制,而非你定义的枚举类本身的__iter__方法。当执行list(MyEnum)时,Python实际调用的是元类EnumMeta实现的__iter__,这个默认实现会自动过滤值重复的成员,只保留每个值对应的第一个成员。
你在枚举类中用@classmethod重写的__iter__根本不会被触发——类本身是元类的实例,迭代类对象时,Python会调用元类的__iter__方法,而非类自身的类方法。
解决方法
方法1:自定义元类,重写迭代逻辑
通过自定义继承自EnumMeta的元类,重写其__iter__方法,就能控制list(MyEnum)的返回结果:
from enum import Enum, EnumMeta class AllMembersEnumMeta(EnumMeta): def __iter__(cls): # 返回所有成员的实例,包含值重复的成员 return iter(cls.__members__.values()) class MyEnum(Enum, metaclass=AllMembersEnumMeta): A = 1 B = 2 C = 3 D = 1 # 和A值相同的成员
测试效果:
>>> list(MyEnum) [<MyEnum.A: 1>, <MyEnum.B: 2>, <MyEnum.C: 3>, <MyEnum.D: 1>]
方法2:直接获取所有成员名称(无需修改枚举类)
如果你的需求只是获取所有成员名称,直接使用list(MyEnum.__members__)即可,这是最简洁的方式:
>>> list(MyEnum.__members__) ['A', 'B', 'C', 'D']
如果一定要通过list(MyEnum)直接返回成员名称列表,可以修改元类的__iter__方法返回名称:
class AllMemberNamesEnumMeta(EnumMeta): def __iter__(cls): return iter(cls.__members__.keys()) class MyEnum(Enum, metaclass=AllMemberNamesEnumMeta): A = 1 B = 2 C = 3 D = 1
测试效果:
>>> list(MyEnum) ['A', 'B', 'C', 'D']
内容的提问来源于stack exchange,提问作者the.real.gruycho
相关产品推荐
相关产品推荐

