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

为何实例化Model2时会打印‘Validator for B1’?

问题:泛型Pydantic模型实例化时意外触发无关Mixin验证器的原因

代码示例

from typing import Any, Dict, Generic, TypeVar, get_args
import pydantic


class Mixin(pydantic.BaseModel):
    @pydantic.root_validator(pre=True)
    def print(cls, values: Dict[str, Any]):
        print(f"Validator for {cls.__name__}")
        return values


class B1(Mixin): ...
class B2(Mixin): ...
BT = TypeVar("BT", B1, B2)


class BaseModel(Generic[BT], pydantic.BaseModel):
    b: BT

    @pydantic.root_validator(pre=True)
    def fill_defaults(cls, values: Dict[str, Any]):
        b_type = get_args(cls.__orig_bases__[0])[0]
        print(f"Filling defaults for {b_type.__name__}")
        if "b" not in values:
            values["b"] = b_type()
        return values


class Model1(BaseModel[B1]): ...
class Model2(BaseModel[B2]): ...


Model2()

实际输出

Filling defaults for B2
Validator for B2
Validator for B1

原因解释

这是因为Pydantic在处理泛型类时会缓存泛型基类的验证器关联链,导致不同泛型实例的验证器上下文出现交叉污染:

  • 当定义Model1(BaseModel[B1])时,Pydantic会将B1的Mixin验证器加入到泛型基类BaseModel的验证器链中并缓存。
  • 后续定义Model2(BaseModel[B2])时,Pydantic没有完全清空泛型基类的验证器缓存,B1的验证器仍留在链中。实例化Model2时,虽然创建的是B2对象,但缓存里的B1验证器也被误触发。

另外,代码中通过__orig_bases__手动获取泛型参数的方式不够规范,这种操作会干扰Pydantic内部的泛型处理逻辑,进一步加剧了验证器缓存的混乱问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 04:49:59