gpt4 book ai didi

python - 为什么FastAPI从路由函数返回时会执行两次Pydantic构造函数?

转载 作者:行者123 更新时间:2023-12-04 12:21:34 31 4
gpt4 key购买 nike

我有一个用例,我想在构建模型时在我的类中创建一些值。但是,当我在调用 API 时将该类返回到 FastAPI 以转换为 JSON 时,构造函数将再次运行,并且我可以获得与原始实例不同的值。
这是一个人为的例子来说明:

class SomeModel(BaseModel):
public_value: str
secret_value: Optional[str]

def __init__(self, **data):
super().__init__(**data)
# this could also be done with default_factory
self.secret_value = randint(1, 5)


def some_function() -> SomeModel:
something = SomeModel(public_value="hello")
print(something)
return something


@app.get("/test", response_model=SomeModel)
async def exec_test():
something = some_function()
print(something)
return something
控制台输出是:
public_value='hello' secret_value=1
public_value='hello' secret_value=1
但是 Web API 中的 JSON 是:
{
"public_value": "hello",
"secret_value": 2
}
当我逐步执行代码时,我可以看到 __init__被调用两次。
先上 build something = SomeModel(public_value="hello") .
其次,出乎我的意料,它在 API 处理程序中 exec_testreturn something称呼。
如果这是在类中设置某些内部数据的错误方法,请告诉我要使用的正确方法。否则,这似乎是其中一个模块的意外行为。

最佳答案

由于您使用的是 response_model 对于路径操作,您的返回值将根据它进行验证。但是由于您返回的是一个已经验证过的模型实例,这会发生两次。如果您不使用变异 __init__ 就不会引起注意无论输入值如何,该方法都可以为模型的每个实例化生成不同的值。
我认为最可取的解决方案是使用 default_factory 函数,因为在这种情况下动态值只会在你的代码中实例化对象的时候生成,而现成的值会在模型验证过程中返回时使用。

class SomeModel(BaseModel):
public_value: str
secret_value: int = Field(default_factory=lambda: randint(1, 5))
如果由于某种原因您不想使用上述方法,那么您可以使用 always validator ,这将允许您检查该值是否已传递或是否需要创建:
class SomeModel(BaseModel):
public_value: str
secret_value: int = None

@validator('secret_value', pre=True, always=True)
def secret_validator(cls, v):
return randint(1, 5) if v is None else v

关于python - 为什么FastAPI从路由函数返回时会执行两次Pydantic构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69090377/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com