允许BaseModel pydantic接受位置参数

7

我有一个带有所有必要参数的类。但是,在init函数中,它要求使用关键字参数,不接受位置参数。因此,我的问题是:在pydantic.BaseModel的配置中是否有我可以更改以允许位置参数的内容?

以下是我的类示例:

class Foo(BaseModel):
    a: int
    b: Optional[str]
    c: Optional[float]

初始化类时需要传递关键字参数:

一个类的参数图像

因此,我不能像这样初始化类:

Foo(1,2,2.5)
# instead, I should init it like this:
Foo(a=1,b=2,c=2.5)

所以,我需要能够将位置关键字传递给类。这是可能的吗?


请参考以下问题及其建议:如何通过位置而非名称来初始化 Pydantic 对象的字段值? - pabouk - Ukraine stay strong
3个回答

6

通过包含类型提示,演示在 PyCharm 中覆盖 __init__ 方法的示例。

class Foo(BaseModel):
    a: int
    b: Optional[str]
    c: Optional[float]
    
    def __init__(self, a: int,
                 b: Optional[str] = None,
                 c: Optional[float] = None,
                 **kwargs) -> None:
        super(Foo, self).__init__(a=a, b=b, c=c, **kwargs)

1

如果您想要支持位置参数,除非您像Arseniy Lebedev建议的那样自己实现,否则Pydantic对象不支持位置参数。

为什么会这样呢?以下是一些原因

  • 当您有很多字段时,向模型添加另一个字段将非常容易,而突然间所有假设字段具有给定位置的代码都会默默地中断。
  • 注释字段意味着pydantic模型字段的顺序与代码中的顺序不同。
import json
from pydantic import BaseModel
from typing import Optional

class Foo(BaseModel):
    a: int
    b: Optional[str]
    c: Optional[float]

你可以使用Pydantic为模型提供任何你想要初始化的键(就像你所做的那样):
Foo(a=1,b="2",c=2.5)

或者您可以使用JSON:

json_raw = '{"a": 1, "b": "2", "c": 3}'
some_dict = json.loads(json_raw)
my_foo = Foo(**some_dict)

或两者的混合:

json_raw = '{"a": 1, "b": "2"}'
some_dict = json.loads(json_raw)
my_foo = Foo(**some_dict, c=3)

1
有没有其他类似于pydantic的库,可以接受位置参数来完成同样的事情?还是我必须自己实现它? - user13699857
2
我找到了一个解决方案,我在我的类中创建了一个init函数,通过使用pydantic.BaseModel的__fields__,它将获取所有位置参数并将其转换为关键字参数。但是我的init函数中,类型提示没有显示出来... 我可以修复这个问题吗? - user13699857

1
不要使用这段代码:
def model_from_args(model, args):
    return model(**{field: arg for field, arg in zip(model.model_fields, args)})

改变模型后,破解代码的可能性非常高。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接