如何为Python Enum子类自定义value属性?解决赋值报错问题
解决Enum子类中无法修改value属性的问题
问题原因
Enum类的value属性是只读属性,由Enum元类在创建成员实例时自动赋值并锁定,无法在__init__方法中直接修改,这就是触发AttributeError的根本原因。
解决方法
重写Enum的__new__方法——这是Python创建对象的首个执行步骤,在__init__之前运行,此时枚举实例尚未被元类完全初始化,可直接设置value属性。
修正后的代码实现
from enum import Enum from dataclasses import dataclass @dataclass class MyDataClass: data: str metadata: dict class MyEnum(Enum): def __new__(cls, my_class_obj): # 创建枚举实例 instance = object.__new__(cls) # 将MyDataClass的data字段设为枚举的value instance.value = my_class_obj.data # 存储metadata到自定义的info属性 instance.info = my_class_obj.metadata return instance # 测试枚举类 class MyObjects(MyEnum): OBJ_1 = MyDataClass('some_data', {'some_field': 1}) OBJ_2 = MyDataClass('some_other_data', {'some_other_field': 2}) # 验证结果 assert MyObjects.OBJ_1.value == 'some_data' assert MyObjects.OBJ_1.info == {'some_field': 1}
实际场景应用(Pydantic模型动态生成枚举)
结合你提到的从Pydantic模型字段动态生成枚举的需求,可以扩展上述实现:
from pydantic import BaseModel, Field from enum import Enum from dataclasses import dataclass @dataclass class FieldMetadata: field_name: str description: str field_type: type class PydanticFieldEnum(Enum): def __new__(cls, field_meta): instance = object.__new__(cls) instance.value = field_meta.field_name # 用字段名作为枚举value instance.description = field_meta.description instance.field_type = field_meta.field_type return instance # 示例Pydantic模型 class User(BaseModel): user_id: int = Field(description="用户唯一ID") username: str = Field(description="用户登录账号") email: str = Field(description="用户联系邮箱") # 动态生成枚举 UserFields = PydanticFieldEnum( 'UserFields', [ (field.name, FieldMetadata(field.name, field.field_info.description, field.type_annotation)) for field in User.model_fields.values() ] ) # 访问枚举信息 print(UserFields.user_id.value) # 输出: user_id print(UserFields.user_id.description) # 输出: 用户唯一ID print(UserFields.user_id.field_type) # 输出: <class 'int'>
内容的提问来源于stack exchange,提问作者Atai Ambus
相关产品推荐
相关产品推荐

