Search code examples
pythondictionarymergepython-dataclasses

Merging two dataclasses


Let A be a dataclass that contains at least the attributes in the dataclass B.

In python, is there a simple way to merge an instance of B and an instance of A in the same way two dictionaries are merged with the | operator as in the example below?

from dataclasses import dataclass, asdict, replace

@dataclass
class A:
    x: int 
    y: int 

@dataclass
class B:
    x: int 

a=A(x=2,y=6)
b=B(x=4)

The current simplest solutions i found were:

  1. To convert both instances to dictionaries, do the merge into a single dictionary, then convert back to dataclass as in the code below:
c_dict : dict = asdict(a) | asdict(b)
c_1=A(**c_dict)
  1. To use the replace function and asdict conversion as in the code below:
c_2=replace(a,**asdict(b))

Is this the simplest way? For instance trying a|b fails as an 'unsupported operand'.


Solution

  • Since there is nothing built-in that will support the a | b behavior, you can implement on your own a mixin class with the __or__ method defined:

    @dataclass
    class Unionable:
        def __or__(self, other):
            return self.__class__(**asdict(self) | asdict(other))
    

    so that:

    @dataclass
    class A(Unionable):
        x: int
        y: int
    
    @dataclass
    class B(Unionable):
        x: int
    
    a = A(x=2, y=6)
    b = B(x=4)
    print(a | b)
    

    outputs:

    A(x=4, y=6)
    

    Demo: https://ideone.com/rEDBzN