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

Pydantic中FieldInfo内的ForwardRef未被update_forward_refs更新导致construct()实例化报错的解决方法咨询

Pydantic中FieldInfo内的ForwardRef未被update_forward_refs更新导致construct()实例化报错的解决方法咨询

这个问题我之前踩过一模一样的坑!确实,update_forward_refs()只会处理字段的类型注解(也就是A.__fields__['b'].type_这部分),但不会自动更新Field参数里的default_factory这类自定义属性——这是Pydantic V1版本的一个小局限。

快速临时解决:手动更新default_factory

在调用update_forward_refs()之后,直接把field_info里的default_factory替换成实际的B类就行,代码示例如下:

from typing import ForwardRef
from pydantic import BaseModel, Field

ClassB = ForwardRef('B', is_class=True)

class A(BaseModel):
    b: ClassB = Field(default_factory=ClassB)
    
    class Config:
        arbitrary_types_allowed = True

class B:
    pass

# 先更新字段的类型引用
A.update_forward_refs()
# 手动替换default_factory为实际的B类
A.__fields__['b'].field_info.default_factory = B

# 现在可以正常调用construct()了
instance = A.construct()
print(instance.b)  # 输出 <__main__.B object at 0x...>

更优雅的写法:调整类定义顺序

如果可以调整代码结构,完全可以等B类定义完成后再给A添加字段,这样就不用依赖ForwardRef了:

from pydantic import BaseModel, Field

class A(BaseModel):
    class Config:
        arbitrary_types_allowed = True

class B:
    pass

# 等B定义好后,动态添加字段
A.__fields__['b'] = Field(default_factory=B, annotation=B)

# 直接调用construct即可
A.construct()

长期推荐方案:升级到Pydantic V2

如果你的项目可以升级到Pydantic V2,这个问题会被自动解决。V2里的model_rebuild()方法会更全面地处理所有引用,包括default_factory里的ForwardRef:

from typing import ForwardRef
from pydantic import BaseModel, Field

ClassB = ForwardRef('B')

class A(BaseModel):
    b: ClassB = Field(default_factory=ClassB)
    
    class Config:
        arbitrary_types_allowed = True

class B:
    pass

# V2用model_rebuild代替update_forward_refs
A.model_rebuild()
# V2里对应的构造方法是model_construct
instance = A.model_construct()

问题根源解释

本质上,update_forward_refs()的设计目标只是解析字段的类型注解(也就是你定义的b: ClassB这部分),而Field(default_factory=ClassB)里的default_factory是作为参数传入的,Pydantic不会自动追踪并更新这个参数里的ForwardRef对象,所以需要我们手动处理。

备注:内容来源于stack exchange,提问作者Jimothy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 11:14:41