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

Pydantic模型中如何基于已有字段值创建新字段

Pydantic 模型创建依赖其他字段的计算字段方案

你原有代码的问题很明确:类定义阶段直接写name = last_name属于静态类属性赋值,执行这行代码时last_name只是Pydantic的字段声明对象,不是模型实例化后的实际属性值,最终实例的name既不会被Pydantic识别为模型字段,也无法动态获取对应实例的last_name取值。另外你代码中last_name标注为int类型不符合姓名的常规数据类型,示例中会一并修正。


不同场景的正确实现方式

1. Pydantic V2 官方推荐方案:计算字段装饰器

如果需要字段动态跟随依赖字段更新,且自动参与模型校验、序列化导出,直接用@computed_field装饰器搭配Python内置的@property即可,这是V2版本专门为这类场景设计的能力:

from pydantic import BaseModel, Field, computed_field

class Info(BaseModel):
    first_name: str | None = Field(None)
    last_name: str | None = Field(None) # 修正原代码last_name的类型错误

    @computed_field
    @property
    def name(self) -> str | None:
        # 可自定义任意取值逻辑,比如拼接姓名:return f"{self.first_name} {self.last_name}"
        return self.last_name

使用时不管是直接访问实例的.name属性,还是调用model_dump()、model_json_schema()等方法,name字段都会正常输出,修改实例的last_name值后name会同步更新。

2. Pydantic V1 兼容方案:属性+模型配置

如果使用V1版本,没有computed_field装饰器,可以直接用Python原生@property实现动态取值,再通过模型配置让属性参与序列化:

from pydantic import BaseModel, Field

class Info(BaseModel):
    first_name: str = Field(None)
    last_name: str = Field(None)

    @property
    def name(self):
        return self.last_name

    class Config:
        keep_untouched = (property,)
        orm_mode = True

3. 固定值场景:校验器预赋值

如果希望name在实例化时就固化取值,后续不随last_name的修改同步变化,可以提前声明name字段,通过模型校验器在实例化阶段完成赋值:

from pydantic import BaseModel, Field, model_validator

class Info(BaseModel):
    first_name: str | None = Field(None)
    last_name: str | None = Field(None)
    name: str | None = Field(None) # 必须提前声明字段

    @model_validator(mode="after")
    def assign_name(self):
        self.name = self.last_name
        return self

注意:这种方案下name是独立存储的普通字段,实例创建完成后修改last_name不会自动更新name的值,仅适合取值固定不需要动态联动的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 07:03:17