Python Pydantic - 如何有一个“可选”字段,但如果存在需要符合非 None 值?

mgc*_*nny 5 python python-3.x pydantic

我正在尝试验证具有“可选”字段的对象,因为它们可能存在也可能不存在。但是当它们存在时,这些字段应该符合特定的类型定义(不是 None)。

在下面的示例中,“大小”字段是可选的,但允许无。我希望“大小”字段是可选的,但如果存在,它应该是一个浮点数。

from pydantic import BaseModel

class Foo(BaseModel):
    count: int
    size: float = None  # how to make this an optional float? 

 >>> Foo(count=5)
 Foo(count=5, size=None)  # GOOD - "size" is not present, value of None is OK


 >>> Foo(count=5, size=None)
 Foo(count=5, size=None) # BAD - if field "size" is present, it should be a float

 # BONUS
 >>> Foo(count=5)
 Foo(count=5)  # BEST - "size" is not present, it is not required to be present, so we don't care about about validating it all.  We are using Foo.json(exclude_unset=True) handles this for us which is fine.
Run Code Online (Sandbox Code Playgroud)

Sti*_* B. 9

可以使用验证器来完成。

from pydantic import BaseModel, ValidationError, validator

class Foo(BaseModel):
    count: int
    size: float = None

    @validator('size')
    def size_is_some(cls, v):
        if v is None:
            raise ValidationError('Cannot set size to None')
        return float(v)
Run Code Online (Sandbox Code Playgroud)

这按预期工作:

>>> Foo(count=5)
Foo(count=5, size=None)

>>> Foo(count=5, size=1.6)
Foo(count=5, size=1.6)

>>> Foo(count=5, size=None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "[venv]/lib/python3.6/site-packages/pydantic/main.py", line 283, in __init__
    raise validation_error
pydantic.error_wrappers.ValidationError: 1 validation error for Foo
size
  Cannot set size to None (type=value_error)
Run Code Online (Sandbox Code Playgroud)

  • 如果你运行 mypy 它会抱怨 size: float = None 因为它没有定义为Optional[float] (2认同)

小智 6

from pydantic import BaseModel
from typing import Optional

class Foo(BaseModel):
    count: int
    size: Optional[float]


obj = Foo(count=5)
obj_2 = Foo(count=5, size=1.6)

# count=5 size=None
print(obj)
# count=5 size=1.6
print(obj_2)
Run Code Online (Sandbox Code Playgroud)

这可能会令人困惑,但输入的可选类型将使您有可能拥有“可选”字段