如何为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
相关产品推荐
相关产品推荐

