如何通过pydantic过滤NaN



如何在pytdantic float验证中过滤掉NaN ?

from pydantic import BaseModel
class MySchema(BaseModel):
float_value: float

您可以使用confloat并将上限设置为无穷大或下限设置为-无穷大。由于与NaN的所有数值比较都返回False,这将使pydantic拒绝NaN,同时保留所有其他行为相同(包括解析,从int到float的转换,…)。

from pydantic import BaseModel, confloat
class MySchema(BaseModel):
float_value: confloat(ge=-float('inf'))
# or:
# float_value: confloat(le=float('inf'))

注意:您还可以通过使用confloatgtlt参数而不是gele来排除无穷值。

测试:

m = MySchema(float_value=float('nan'))
输出:

pydantic.error_wrappers.ValidationError: 1 validation error for MySchema
float_value
ensure this value is greater than or equal to -inf (type=value_error.number.not_ge; limit_value=-inf)

pydantic版本>= 1.10的最新答案是使用confloat并相应地设置其allow_inf_nan:

class Finite(BaseModel):
value: confloat(allow_inf_nan=False)

这样,参数float("inf")-float("inf")float("nan")-float("inf")将产生一个ValidationError

参见confloat的文档

import maths
from pydantic import BaseModel, validator
class MySchema(BaseModel):
float_value: float
@validator('*', pre=True)
def split_str(cls, v):
if isinstance(v, float):
if maths.isnan(v):
raise ValueError("value can't be Not-a-Number (NaN)")
return v
return v   

为验证定义您的自定义类型,在pydantic:

有很好的文档
class NoNanFloat(float):

@classmethod
def __get_validators__(cls):
yield cls.validate

@classmethod
def __modify_schema__(cls, field_schema):
# you can ommit this method
field_schema.update(
examples=['24.2,15.2'],
)
@classmethod
def validate(cls, v):
if not isinstance(v, float):
raise TypeError('float required')
if v!=v: # you can use here also maths.isnan(v):
raise ValueError("value can't be Not-a-Number (NaN)")
return cls(v)
def __repr__(self):
# you can also ommit this method, but it looks good when printing. 
return f'NoNanFloat({super().__repr__()})'

class MySchema(BaseModel):
no_nan_float_value: NoNanFloat
other_float_value: float
other: Any

这种方法有很多优点,因为它允许你有两种类型的"float "这取决于你的需要,所以你可以有一些允许nan和其他不允许。

I还允许您使用"Any"类型接受nan,并且类型的联合行为符合预期。

最新更新