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

如何为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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 21:05:48