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

Pydantic模型中typing.Optional[]两种定义方式的区别解析

关于Pydantic中typing.Optional[]隐式与显式赋值None的技术区别

在Pydantic模型定义时,a: typing.Optional[int](隐式声明可选)和a: typing.Optional[int] = None(显式指定默认值为None)两种写法,实例化后字段最终值都是None,但二者存在以下技术差异:

示例代码

import typing
import pydantic


class Bar(pydantic.BaseModel):
    a: typing.Optional[int]

    @pydantic.validator('a', always=True, pre=True)
    def check_a(cls, v, values, field):
        print("WITHOUT NONE")
        print(values)
        print(field)
        return v


class Baz(pydantic.BaseModel):
    a: typing.Optional[int] = None

    @pydantic.validator('a', always=True, pre=True)
    def check_a(cls, v, values, field):
        print("WITH NONE")
        print(values)
        print(field)
        return v


print(Bar())
print(Baz())

输出结果

WITHOUT NONE
{}
name='a' type=Optional[int] required=False default=None
a=None
WITH NONE
{}
name='a' type=Optional[int] required=False default=None
a=None

具体技术差异

  • 默认值的来源不同
    隐式写法里,Optional仅标记字段类型允许为None,字段的默认值None是Pydantic基于类型规则自动补充的;显式写法则是开发者主动为字段指定默认值为None。从输出的field信息能看到两者最终都有default=None,但底层逻辑上一个是框架自动推断,一个是开发者显式声明。

  • 复杂场景下的行为差异
    比如使用exclude_unset参数序列化模型时:隐式声明的可选字段如果从未被赋值,在部分Pydantic版本中会被排除在序列化结果外;而显式赋值None的字段,即使没被修改,也会被视为“已设置”,会出现在序列化结果中。另外在模型继承、结合Field函数自定义字段规则时,显式默认值的优先级会高于框架自动补充的默认值。

  • 语义表达的清晰度不同
    隐式写法侧重表达“字段类型可选,可接受None”;显式写法除了说明类型可选,还明确告知“字段默认值就是None”,在团队协作中更清晰,能减少对字段默认行为的歧义理解。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 20:20:05