Home > Back-end >  How do I return a child class instance after running a super class method?
How do I return a child class instance after running a super class method?

Time:12-08

I have 2 python classes one subclasses the other

class A:
    def __init__(some params):
        do something()

    def method(params):
        return A_new_A_instance

class B(A)
    def __init__(some params):
        super().__init__(some params)

    def new_method(params):
        a_instance=super.method(params)
        return B(a)
        

The above works fine for some of the methods I'm using heavily.

The issue is that class A has a lot of methods some I'm using as is others I'm modifying etc. And a few I don't care about. Most of the methods in A returns another instance of A (like selecting, adding, re-ordering data) But I want to make sure that whichever A.method() I call I want return an instance of B when I do B.method().

Is there a magic way to do this for all methods of A or do I need to over them one by one?

CodePudding user response:

As long as the constructor of both A and B are the same (they take the same parameters) you can use a factory function to create new instances of A and override it for B:

class A:
    def __init__(self, *params):
        pass

    def _create_new_instance(self, *params):
        return A(*params)

    def method(self, *params):
        # this will either call A._create_new_instance or
        # B._create_new_instance depending on type(self)
        return self._create_new_instance(*params)

class B(A):
    def __init__(self, *params):
        super().__init__(self, *params)

    def _create_new_instance(self, *params):
        return B(*params)

    def new_method(self, *params):
        new_b = self.method(*params)
        do_something_new(new_b)
        return new_b

assert isinstance(A().method(), A)
assert isinstance(B().method(), B)

CodePudding user response:

I guess I did not word my question properly.

I was looking for a way to use the existing methods from the superclass in the subclass without knowing what they are (or not bothering to know).

The solution I came up with is follows:

have a function that queries available methods in the superclass

def get_methods(class_instance):
    method_list = [attribute for attribute in dir(class_instance) if callable(getattr(class_instance, attribute))
                   and attribute.startswith('__') is False]
    return 

then you can put something like this in the __init__ to get those methods into the subclass. I'm avoiding the __ methods, since I do not care about most of them and also want to set some of them myself later on like __str__ or __add__.

methods=get_methods(super())
        for method_name in methods:
            method = getattr(super(), method_name)
            self.__setattr__(method_name, classmethod(method))
  • Related