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

如何在Pydantic中访问PrivateAttr的更新后值?

问题:Pydantic私有属性复制后属性访问异常

我定义了如下Pydantic类:

from pydantic import BaseModel, PrivateAttr


class A(BaseModel):
    _value: str = PrivateAttr()

    def __init__(self):
        self._value = "Initial Value"
        super().__init__()

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, some_value: str):
        self._value = some_value

    def clone(self):
        return self.copy(update={"_value": "Updated Value"})

当实例化该类并通过clone方法复制实例、更新私有属性_value后,打印实例能看到副本的_value已更新,但访问副本的value属性却仍得到初始值。执行以下测试代码:

a = A()
b = a.clone()
print([a, b])
print(a.value)
print(b.value)

得到输出:

[A(), A(_value='Updated Value')]
Initial Value
Initial Value

请问如何正确获取更新后的值?


原因分析

Pydantic的copy()方法处理私有属性时,会将更新的私有属性存储在实例的__private_attributes__字典中,但自定义的@property直接访问的是__init__中创建的普通实例属性self._value,两者并非同一存储位置。

在__init__中直接给self._value赋值时,会在实例上生成一个独立的普通属性,而Pydantic管理的私有属性实际由__private_attributes__维护。copy()更新的是Pydantic管控的私有属性,value属性读取的却是手动创建的_value实例属性,因此无法获取到更新后的值。

解决方案

方案1:统一使用Pydantic私有属性访问逻辑

修改value属性的读写逻辑,直接操作Pydantic管理的私有属性存储:

from pydantic import BaseModel, PrivateAttr


class A(BaseModel):
    _value: str = PrivateAttr(default="Initial Value")

    def __init__(self, **data):
        super().__init__(**data)

    @property
    def value(self):
        return self.__private_attributes__["_value"].get(self)

    @value.setter
    def value(self, some_value: str):
        self.__private_attributes__["_value"].set(self, some_value)

    def clone(self):
        return self.copy(update={"_value": "Updated Value"})

方案2:通过Pydantic初始化逻辑设置私有属性

避免在__init__中直接赋值self._value,改用Pydantic的初始化参数传递私有属性值:

from pydantic import BaseModel, PrivateAttr


class A(BaseModel):
    _value: str = PrivateAttr()

    def __init__(self):
        super().__init__(_value="Initial Value")

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, some_value: str):
        self._value = some_value

    def clone(self):
        return self.copy(update={"_value": "Updated Value"})

修改后再次运行测试代码,b.value将正确返回"Updated Value"。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 14:10:45