从其他数据类实例填充数据类实例



我有一个场景,我有两个数据类共享一些命令键。假设

@dataclass
class A
key1: str = ""
key2: dict = {}
key3: Any = ""

和B类

@dataclass
class B
key1: str = ""
key3: Any = ""
key4: List = []

这两个类共享一些键值。现在我想把A类的通用键值赋给B类实例。

我知道的一种方法是将类转换为dict对象,然后将其转换回数据类对象。但据我所知,数据类的唯一目的是有效地存储数据和管理。我相信有更好的办法。

预期输入与输出

# State of dataclass A while B is not initialized
A(key1: "key1value", Key2: {"a": "a"}, key3: [1,2])
# State of B should be
B(key1: "key1value",key3: [1,2], key4: [])

您可以使用signature获取类的所有属性,然后getattr检查键是否具有相同的名称,最后setattr更改classB的值,如下所示:

from dataclasses import dataclass, field
from inspect import signature
from typing import Any, List, Dict
def main():
instanceA, instanceB = A("key1value", {"a": "a"}, [1,2]), B()
attrsA, attrsB = signature(A).parameters, signature(B).parameters
for attr in attrsA:
if attr in attrsB:
valueA = getattr(instanceA, attr)
setattr(instanceB, attr, valueA)
@dataclass
class A:
key1: str = ""
key2: Dict[str, str] = field(default_factory=dict)
key3: Any = ""
@dataclass
class B:
key1: str = ""
key3: Any = ""
key4: List = field(default_factory=list)

if __name__ == '__main__':
main()

赋值前的实例:

A(key1='key1value', key2={'a': 'a'}, key3=[1, 2])
B(key1='', key3='', key4=[])

:后

A(key1='key1value', key2={'a': 'a'}, key3=[1, 2])
B(key1='key1value', key3=[1, 2], key4=[])

如果你在你的类中添加了一个方法,你可以为任何类做它,并让它从a到B或B到a

我看到的签名的问题是,如果您在init中进行任何更改例如,为B设置类A作为参数,它将不再工作。

from dataclasses import dataclass, field, fields
from typing import Any
@dataclass
class A:
key1: str = ""
key2: dict = field(default_factory=dict)
key3: Any = ""
def set_keys(self, other):
self_fields = list(map(lambda x: x.name,  fields(self)))
for _field in fields(other):
if _field.name in self_fields:
setattr(self, _field.name, getattr(other, _field.name))
@dataclass
class B:
key1: str = ""
key3: Any = ""
key4: list = field(default_factory=list)
def set_keys(self, other):
self_fields = list(map(lambda x: x.name,  fields(self)))
for _field in fields(other):
if _field.name in self_fields:
setattr(self, _field.name, getattr(other, _field.name))
a = A(key1="key1value", key3=[1, 2])
b = B()
b.set_keys(a)

结果:

A(key1='key1value', key2={'a': 'a'}, key3=[1, 2])
B(key1='key1value', key3=[1, 2], key4=[])

最新更新