自定义Python Enum默认返回值遇递归错误及后续问题求助
解决Python Enum直接返回值的递归问题及相关遍历、字典键问题
问题分析
你尝试通过自定义元类让Enum类属性直接返回对应值,但触发RecursionError,原因是原元类的__getattribute__会处理所有类属性访问,包括Enum内部依赖的核心属性(如__members__)。当这些非枚举成员属性被访问时,尝试获取.value会抛出AttributeError,而Enum内部流程会反复调用该方法,最终导致递归溢出。
同时,遍历枚举时返回的是枚举实例而非值,以及枚举实例作为字典键时与对应字符串不等价的问题,本质是枚举实例的默认行为未与值对齐。
优雅解决方案
1. 修正元类避免递归
自定义元类仅对枚举成员返回对应值,其余属性正常返回:
from enum import Enum, EnumMeta class EnumDirectValueMeta(EnumMeta): def __getattribute__(cls, name): # 直接获取__members__,避免触发自定义__getattribute__导致递归 members = object.__getattribute__(cls, '__members__') if name in members: return members[name].value # 非枚举成员属性直接返回原属性 return object.__getattribute__(cls, name)
2. 让枚举迭代直接返回值+兼容字典键
重写枚举类的迭代方法,同时让枚举实例与对应值的哈希、相等性对齐:
class AutoValueEnum(Enum): # 让枚举实例与对应值的哈希、相等性对齐,解决字典键匹配问题 def __hash__(self): return hash(self.value) def __eq__(self, other): return self.value == other class Currency(AutoValueEnum, metaclass=EnumDirectValueMeta): USD = "USD" EUR = "EUR" GBP = "GBP" @classmethod def __iter__(cls): # 遍历枚举时返回值而非实例 return (member.value for member in super().__iter__())
验证效果
- 直接访问类属性:
print(Currency.USD)→ 输出USD - 遍历枚举:
[ccy for ccy in Currency]→ 返回['USD', 'EUR', 'GBP'] - 字典键兼容:无论是
balance[Currency.USD]还是balance[ccy](ccy为遍历得到的值或枚举实例),都能正常获取值
内容的提问来源于stack exchange,提问作者mxsx
相关产品推荐
相关产品推荐

