You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 05:35:01