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

如何在Pydantic中重写父类的@property装饰属性

解决Pydantic子类重写父类@property属性的问题

问题原因

父类中用@property装饰的name_new会被Pydantic识别为模型属性,子类直接赋值name_new = 'foo_bar_foo'会被当成新字段,和父类属性冲突导致报错。而使用alias的方式只是创建了一个别名字段,并不会覆盖父类的@property方法,所以访问c.name_new时仍然调用父类的逻辑。

解决方案

方案1:直接重写子类的@property方法

在子类中重新定义带@property装饰的name_new方法,直接覆盖父类的实现:

from pydantic import BaseModel

class Parent(BaseModel):
    name: str = 'foo bar'
    
    @property
    def name_new(self):
        return f"{'_'.join(self.name.split(' '))}"

class Child(Parent):
    @property
    def name_new(self):
        return 'foo_bar_foo'

c = Child()
print(c.name_new)  # 输出: foo_bar_foo

方案2:将name_new转为子类的字段(可选)

如果希望name_new作为Pydantic的可序列化字段,而非动态计算的property,可以在子类中定义该字段,并通过配置确保父类的property被覆盖:

from pydantic import BaseModel

class Parent(BaseModel):
    name: str = 'foo bar'
    
    @property
    def name_new(self):
        return f"{'_'.join(self.name.split(' '))}"

class Child(Parent):
    name_new: str = 'foo_bar_foo'
    
    model_config = {
        # 确保字段优先于父类的property
        'fields': {'name_new': {'alias': 'name_new'}}
    }

c = Child()
print(c.name_new)  # 输出: foo_bar_foo
print(c.model_dump())  # 输出: {'name': 'foo bar', 'name_new': 'foo_bar_foo'}

说明

  • 方案1适合仅需改变动态计算逻辑的场景,保持name_new为只读属性。
  • 方案2适合需要将name_new作为可配置、可序列化的模型字段的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 03:16:15