In Python, is there any way to call a child class's method override from its parent class?

Viewed 34

I'm trying to re-teach myself Python and figure out the specific details, tips and tricks, and common conventions around abstract classes and polymorphism. Right now, I have a class hierarchy that looks like this:

from abc import ABC, abstractmethod


class A(ABC):

    @abstractmethod
    def x(self):
        pass

    def do_x_ten_times(self):
        for i in range(10):
            x()


class B(A):

    def x(self):
        print("Hello World")


class C(A):

    def x(self):
        print("Hello StackOverflow")



b = B()
b.x()

c = C()
c.x()

b.do_x_ten_times()

My thinking is that do_x_ten_times() would be the same exact code in both subclasses B and C. So it would be convenient (and my code would be less repetitive) if I could just put the code for do_x_ten_times() in A, and have A call whatever the subclass's implementation of x() is. Unfortunately, I get "NameError: name 'x' is not defined."

I get why might not be typical to do something like this, and my gut says that it probably goes against certain rules of polymorphism. If I really need to, I'm fine copypastying do_x_ten_times() into both classes B and C, and making it abstract in A. But I'm wondering if there's any reasonable way around having to repeat this code.

1 Answers

You need to call self.x() in A.do_x_ten_times()

from abc import ABC, abstractmethod


class A(ABC):

    @abstractmethod
    def x(self):
        raise NotImplementedError

    def do_x_ten_times(self):
        for i in range(10):
            self.x()        # <-- self will refer to the calling instance
                            #     implementation of x(self)


class B(A):

    def x(self):
        print("Hello World")


class C(A):

    def x(self):
        print("Hello StackOverflow")



b = B()
b.x()

c = C()
c.x()

b.do_x_ten_times()
Related