如何在 pytdantic 浮点验证中过滤掉 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'))
注意:您还可以使用
gt
的 lt
和 confloat
参数而不是 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)
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
这种方法有很多优点,因为它允许您根据需要拥有两种类型的“浮动”,因此您可以有一些允许 nan 和其他不允许的。
我还允许您使用接受 nan 的“任何”类型,以及按预期行为的类型联合。