如何在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'))
注意:您还可以通过使用confloat
的gt
和lt
参数而不是ge
和le
来排除无穷值。
测试:
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,并且类型的联合行为符合预期。