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

如何在Pydantic的float类型校验中过滤NaN值

Pydantic float字段过滤NaN值实现方案

Pydantic 默认不会拦截float('nan')这类特殊浮点值,因为NaN本身属于Python原生float类型范畴,要实现NaN的校验拦截或自动过滤,可直接通过字段校验器实现,适配所有主流Pydantic版本。


方案1:单字段校验(最灵活,推荐)

针对单个字段添加校验逻辑,可根据需求选择直接抛错拦截NaN,或者自动替换NaN为默认值实现过滤。

Pydantic V2 写法(当前主流版本)

import math
from pydantic import BaseModel, field_validator

class MySchema(BaseModel):
    float_value: float

    @field_validator("float_value")
    @classmethod
    def check_nan(cls, value: float) -> float:
        # 拦截NaN,抛出校验错误
        if math.isnan(value):
            raise ValueError("浮点值不能为NaN")
        return value

如果需要自动过滤NaN、不抛错,直接把NaN替换为指定默认值(比如None、0),可调整校验逻辑,同时对应修改字段类型:

import math
from typing import Optional
from pydantic import BaseModel, field_validator

class MySchema(BaseModel):
    # NaN会被替换为None,所以字段标记为Optional
    float_value: Optional[float] = None

    @field_validator("float_value")
    @classmethod
    def filter_nan(cls, value: float) -> Optional[float]:
        if isinstance(value, float) and math.isnan(value):
            # 遇到NaN直接返回默认值,完成异常值过滤
            return None
        return value

Pydantic V1 兼容写法

如果使用1.x版本的Pydantic,把field_validator替换为validator即可,其余逻辑一致:

import math
from pydantic import BaseModel, validator

class MySchema(BaseModel):
    float_value: float

    @validator("float_value")
    def check_nan(cls, value: float) -> float:
        if math.isnan(value):
            raise ValueError("浮点值不能为NaN")
        return value

方案2:自定义通用类型(适合多字段复用)

如果项目中大量float字段都需要过滤NaN,不需要每个字段重复写校验器,可以自定义一个通用的非NaN浮点类型,全局复用:

import math
from pydantic import BaseModel, GetCoreSchemaHandler
from pydantic_core import core_schema
from typing import Any

class SafeFloat(float):
    """自动拦截NaN、无穷值的安全浮点类型"""
    @classmethod
    def __get_pydantic_core_schema__(
        cls, source_type: Any, handler: GetCoreSchemaHandler
    ) -> core_schema.CoreSchema:
        def validate(value: float) -> float:
            if math.isnan(value) or math.isinf(value):
                raise ValueError("浮点值不能为NaN或无穷值")
            return cls(value)
        return core_schema.no_info_plain_validator_function(validate)

# 所有模型直接引用该类型即可,无需重复写校验逻辑
class MySchema(BaseModel):
    float_value: SafeFloat

注意事项

  • 判断NaN优先使用math.isnan(),不要依赖value != value的NaN特性判断,后者可读性差,还可能被自定义浮点类的等于方法重载逻辑干扰。
  • 如果需要同时过滤正无穷、负无穷值,在校验逻辑中追加math.isinf(value)判断即可。
  • 校验器逻辑会在类型转换完成后执行,传入的字符串格式数字会先被Pydantic转为float,再进入NaN判断逻辑,无需额外处理类型转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 02:36:52