tri*_*ous 9 python python-3.x pydantic
我有以下型号
class Window(BaseModel):
size: tuple[int, int]
Run Code Online (Sandbox Code Playgroud)
我想像这样实例化它:
fields = {'size': '1920x1080'}
window = Window(**fields)
Run Code Online (Sandbox Code Playgroud)
当然,这会失败,因为 的值'size'
不是正确的类型。但是,我想添加逻辑,以便该值在 处分割x
,即:
def transform(raw: str) -> tuple[int, int]:
x, y = raw.split('x')
return int(x), int(y)
Run Code Online (Sandbox Code Playgroud)
Pydantic 支持这个吗?
ye *_*obe 13
Pydantic 2.0 引入了field_validator
装饰器,它可以让您以非常简单的方式实现这样的行为。给定原始解析函数:
from pydantic import BaseModel, field_validator
class Window(BaseModel):
size: tuple[int, int]
@field_validator("size", mode="before")
@classmethod
def transform(cls, raw: str) -> tuple[int, int]:
x, y = raw.split("x")
return int(x), int(y)
Run Code Online (Sandbox Code Playgroud)
笔记:
cls
。将其实现为实例方法(使用self
)会引发错误。mode="before"
的 在这里至关重要,正如预期的那样,这就是使方法在检查“size”是否为元组之前运行的原因。您可以使用 pydantic 来实现这样的行为validator
。给定您的预定义函数:
def transform(raw: str) -> tuple[int, int]:
x, y = raw.split('x')
return int(x), int(y)
Run Code Online (Sandbox Code Playgroud)
你可以在你的类中实现它,如下所示:
from pydantic import BaseModel, validator
class Window(BaseModel):
size: tuple[int, int]
_extract_size = validator('size', pre=True, allow_reuse=True)(transform)
Run Code Online (Sandbox Code Playgroud)
请注意pre=True
传递给验证器的参数。这意味着它将在检查是否为元组的默认验证器之前运行。size
现在:
fields = {'size': '1920x1080'}
window = Window(**fields)
print(window)
# output: size=(1920, 1080)
Run Code Online (Sandbox Code Playgroud)
请注意,此后,您将无法使用Window
大小元组实例化您的。
fields = {'size': '1920x1080'}
window = Window(**fields)
print(window)
# output: size=(1920, 1080)
Run Code Online (Sandbox Code Playgroud)
为了克服这个问题,如果通过稍微改变代码来传递元组,您可以简单地绕过该函数:
派丹提克 2.x
fields2 = {'size': (800, 600)}
window2 = Window(**fields2)
# AttributeError: 'tuple' object has no attribute 'split'
Run Code Online (Sandbox Code Playgroud)
派丹提克 1.x
class Window(BaseModel):
size: tuple[int, int]
@field_validator("size", mode="before")
def transform(cls, raw: str | tuple[int, int]) -> tuple[int, int]:
if isinstance(raw, tuple):
return raw
x, y = raw.split("x")
return int(x), int(y)
Run Code Online (Sandbox Code Playgroud)
这应该给出:
def transform(raw: str | tuple[int, int]) -> tuple[int, int]:
if isinstance(raw, tuple):
return raw
x, y = raw.split('x')
return int(x), int(y)
class Window(BaseModel):
size: tuple[int, int]
_extract_size = validator('size', pre=True, allow_reuse=True)(transform)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
10647 次 |
最近记录: |