在 Pydantic BaseModel 中实例化后更改字段 class

Alter field after instantiation in Pydantic BaseModel class

使用如下 Pydantic class,我想通过应用 replace 操作来转换 foo 字段:

from typing import List
from pydantic import BaseModel

class MyModel(BaseModel):
    foo: List[str]

my_object = MyModel(foo="hello-there")
my_object.foo = [s.replace("-", "_") for s in my_object.foo]

如何在创建对象时直接在 class 中执行 replace 操作?如果没有 Pydantic,我会在 __init(self, foo) 内简单地执行此操作,但由于 Pydantic 创建了自己的 __init__ 实现,我不确定如何进行。

使用花哨的 BaseModel

看来您必须覆盖 basemodels init 方法,如下所示:

from typing import List
from pydantic import BaseModel

class MyModel(BaseModel):
    foo: List[str]

    def __init__(self, **data):
        data["foo"] = [s.replace("-", "_") for s in data["foo"]]
        super().__init__(**data)

my_object = MyModel(foo=["hello-there"])

print(my_object)
# Outputs foo=['hello_there']

使用 Pydantic 数据类

... 或者你也可以把它变成一个 pydantic 数据类,并使用 pydantic 提供的 post init dunder 在实例化时做其他事情。例如:

from typing import List
from pydantic.dataclasses import dataclass

@dataclass
class MyModel():
    foo: List[str]

    def __post_init__(self):
        self.foo = [s.replace("-", "_") for s in self.foo]

my_object = MyModel(foo=["hello-there"])

print(my_object)

# Outputs foo=['hello_there']

使用 @validator 装饰器(在本例中使用选项 each_item=True,因为我们希望验证器查看列表中的每个项目而不是列表本身):

from typing import List
from pydantic import BaseModel, validator

class MyModel(BaseModel):
    foo: List[str]

    @validator('foo', each_item=True)
    def replace_hyphen(cls,v):
        return v.replace("-","_")

my_object = MyModel(foo=["hello-there"])

print(my_object)
# Outputs foo=['hello_there']

或者如果您更喜欢数据类:

from typing import List
from pydantic import validator
from pydantic.dataclasses import dataclass

@dataclass
class MyModelDC():
    foo: List[str]

    @validator('foo', each_item=True)
    def replace_hyphen(cls,v):
        return v.replace("-","_")

my_objectDC = MyModelDC(foo=["hello-there"])

print(my_objectDC)
# Outputs foo=['hello_there']