Skip to content
Advertisement

populate dataclass instance from other dataclass instance

I have a scenario where I’ve two dataclass which share some command keys. Let’s say

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

and class B

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

Both of this class share some key value. Now I want to assign those common key value from class A to to class B instance.

One way I know is to convert both the class to dict object do the process and convert it back to dataclass object. But from what I know sole purpose of dataclass is to effectively store data and manage. I believe there is some better approach.

Expected Input and Output

# 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: [])

Advertisement

Answer

You can use signature to get all the attributes of your class, then getattr to check if keys have the same name, and finally setattr to change the value of classB, something like this:

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()

Instances before assign:

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

After:

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