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

如何为Enum子类定义__new__方法?解决自定义代码枚举报错

解决枚举类继承时的AttributeError问题及代码优化

你遇到的AttributeError是因为自定义的CodeEnum.__new__方法没有正确触发Enum类的初始化流程,导致枚举成员缺少_name_这个Enum内部依赖的属性。Enum在创建成员时会自动注入_name_、_value_等属性,但你的实现直接返回了Code类的实例,跳过了Enum的初始化步骤,从而引发错误。

以下是修正后的完整代码:

import enum

class Code(str):
    def __new__(cls, code: str) -> 'Code':
        if not code.isdigit():
            raise ValueError("code must be digits")
        return super().__new__(cls, code)

class CodeEnum(Code, enum.Enum):
    def __new__(cls, code: str, text: str) -> 'CodeEnum':
        # 先创建Code实例完成数字格式验证
        code_instance = Code(code)
        # 调用Enum的初始化逻辑,生成合法的枚举成员
        obj = super().__new__(cls, code_instance)
        # 设定枚举成员的实际值为验证后的字符串代码
        obj._value_ = code_instance
        # 附加关联的标准文本
        obj.text = text
        return obj

# 示例代码集
class CodeSet1(CodeEnum):
    CODE_0001 = "0001", "Code 0001"
    CODE_0002 = "0002", "Code 0002"

# 测试验证
if __name__ == "__main__":
    print(CodeSet1.CODE_0001.name)    # 输出 CODE_0001
    print(CodeSet1.CODE_0001.value)   # 输出 0001
    print(CodeSet1.CODE_0001.text)    # 输出 Code 0001
    
    # JSON序列化测试,直接输出代码值
    import json
    print(json.dumps(CodeSet1.CODE_0001.value))  # 输出 "0001"

核心优化点

  • 修正初始化流程:通过super().__new__(cls, code_instance)触发Enum的初始化逻辑,确保枚举成员获得_name_等必要属性。
  • 保留代码验证:复用Code类的数字格式校验逻辑,确保所有代码都是纯数字字符串。
  • 满足序列化需求:枚举成员的value是字符串类型的代码,JSON序列化时直接输出代码值,无需额外处理。
  • 复用性保留:所有代码集只需继承CodeEnum,按成员名 = 代码值, 关联文本的格式定义即可。

内容的提问来源于stack exchange,提问作者EQLTThatcher

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 12:45:17