Search code examples
pythoninheritance

If I already have an instance of a super class, how can I create an instance of a child class from it?


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?


Solution

  • @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: