如何让pydantic.dataclass传入None时抛出ValidationError?
问题解决:pydantic.dataclass 中 age 字段传入 None 未触发校验的处理方案
核心原因分析
- 若字段类型声明为
Optional[int],或未明确禁止None,pydantic 会默认允许传入None,不会触发校验错误。 - 自定义
__init__方法会覆盖 pydantic 自动生成的带校验逻辑的构造方法,导致默认校验失效。
解决方案
方案1:不自定义__init__,依赖默认校验逻辑
确保字段类型为严格的int(非Optional[int]),并通过Field标记必填及取值范围:
from pydantic.dataclasses import dataclass from pydantic import Field @dataclass class MyClass: name: str # ... 标记必填,ge/le 设置取值范围 age: int = Field(..., ge=0, le=120) # 测试:传入 None 会直接触发 ValidationError try: obj = MyClass("foo", None) except Exception as e: print(e)
方案2:自定义__init__时手动触发校验
如果必须自定义构造方法,需手动引入 pydantic 的校验逻辑,推荐两种方式:
方式A:用@validate_arguments装饰__init__
from pydantic.dataclasses import dataclass from pydantic import Field, validate_arguments @dataclass class MyClass: name: str age: int = Field(..., ge=0, le=120) @validate_arguments def __init__(self, name: str, age: int): self.name = name self.age = age # 测试:传入 None 触发校验错误 try: obj = MyClass("foo", None) except Exception as e: print(e)
方式B:在__init__中调用 pydantic 内置校验方法
from pydantic.dataclasses import dataclass from pydantic import Field @dataclass class MyClass: name: str age: int = Field(..., ge=0, le=120) def __init__(self, name: str, age: int): self.name = name self.age = age # 触发 pydantic 内置的校验逻辑 self.__post_init_post_parse__() # 测试:传入 None 触发校验错误 try: obj = MyClass("foo", None) except Exception as e: print(e)
方案3:用__post_init__处理自定义逻辑(推荐)
若仅需在初始化后执行额外逻辑,无需完全重写构造方法,优先使用__post_init__,保留 pydantic 默认校验:
from pydantic.dataclasses import dataclass from pydantic import Field @dataclass class MyClass: name: str age: int = Field(..., ge=0, le=120) def __post_init__(self): # 自定义初始化逻辑,此时参数已通过校验 print(f"{self.name} 的年龄 {self.age} 符合要求") # 测试:传入 None 先触发校验错误,不会执行 __post_init__ try: obj = MyClass("foo", None) except Exception as e: print(e)
内容的提问来源于stack exchange,提问作者J'e
相关产品推荐
相关产品推荐

