我有一个pydantic类:
class SomeData(BaseModel):
id: int
x: str
y: str
z: str
假设我有两个这个类的对象obj1 obj2
是否有任何简单的方法,我可以复制obj2,到obj1,而忽略字段的子集?例如,复制所有SomeData字段,除了[id,z]
查看model.copy(...)
(docs)和model.dict(...)
(docs) -特别是update: dict
和exclude: set[str]
参数。
给定SomeData的两个实例(obj1和obj2),用obj2中不包括某些字段的值更新obj1变量:
obj1 = SomeData(id=1, x='x', y='y', z='z')
obj2 = SomeData(id=2, x='x2', y='y2', z='z2')
obj1 = obj1.copy(update=obj2.dict(exclude={"id", "z"}))
# obj1 -> SomeData(id=1, x='x2', y='y2', z='z')
注意,这会创建一个新的副本,而不是改变原来的副本。
要从obj1创建obj2(不包括字段),可以直接使用.copy(exclude=...)
:
obj1 = SomeData(id=1, x='x', y='y', z='z')
obj2 = obj1.copy(exclude={"id", "z"})
# obj2 -> SomeData(x='x', y='y')
如果obj1
和obj2
都已经初始化,并且你想用obj2
上这些字段的值覆盖obj1
的某些字段,你需要自己实现。
这样就可以了:
from collections.abc import Container, Iterable
from typing import Any
from pydantic import BaseModel
class SomeData(BaseModel):
id: int
x: str
y: str
z: str
def update(
self,
other: Iterable[tuple[str, Any]],
exclude: Container[str] = (),
) -> None:
for field_name, value in other:
if field_name not in exclude:
setattr(self, field_name, value)
obj1 = SomeData(id=1, x="a", y="b", z="c")
obj2 = SomeData(id=2, x="foo", y="bar", z="baz")
obj1.update(obj2, exclude={"id", "z"})
print(obj1)
输出:id=1 x='foo' y='bar' z='c'