How do I properly inherit data from an instantiation of a super class? For example, consider something I can get to work, but is confusing in its behaviour:
from dataclasses import dataclass
from typing import Self
@dataclass
class SuperClass:
hello: int
world: int
@dataclass
class ChildClass(SuperClass):
kitty: int
@classmethod
def from_super(cls, s: SuperClass, kitty: int) -> Self:
x = cls(s, kitty=kitty)
return x
Now, let's see whether this works:
super_instance = SuperClass(0, 1)
child = ChildClass.from_super(super_instance, 2)
child
This produces output:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[48], line 1
----> 1 ChildClass.from_super(super_instance, 2)
Cell In[46], line 15
13 @classmethod
14 def from_super(cls, s: SuperClass, kitty: int) -> Self:
---> 15 x = cls(s, kitty=kitty)
16 return x
TypeError: ChildClass.__init__() missing 1 required positional argument: 'world'
So how do I do this correctly, without manually writing out each variable instantiation from the super class?
@classmethod def from_super(cls, s: SuperClass, kitty: int) -> Self: x = cls(s, kitty=kitty) return x
Here, if you do not want to list all arguments for cls
explicitly, instead of passing an instance s
of the superclass, you need to create from s
either a tuple of values which you can pass as positional arguments *args
, or a dictionary of parameter names and values which you can pass as keyword arguments **kwargs
.
Since you are using simple dataclasses, this is easy:
Either using dataclasses.astuple
:
x = cls(*astuple(s), kitty=kitty)
Or using dataclasses.asdict
:
x = cls(**asdict(s), kitty=kitty)