Есть ли в Python способ вызвать переопределение метода дочернего класса из его родительского класса? - PullRequest
3 голосов
/ 16 июня 2019

Я пытаюсь переучить себя на Python и выяснить конкретные детали, советы и хитрости, а также общие соглашения вокруг абстрактных классов и полиморфизма.Прямо сейчас у меня есть иерархия классов, которая выглядит следующим образом:

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()

Я думаю, что do_x_ten_times () будет одинаковым точным кодом в обоих подклассах B и С .Поэтому было бы удобно (и мой код был бы менее повторяющимся), если бы я мог просто поместить код для do_x_ten_times () в A и иметь вызов A независимо от реализации подкласса х () есть.К сожалению, я получаю «NameError: name 'x' не определено».

Я понимаю, почему может быть нехарактерно делать что-то подобное, и моя интуиция говорит, что это, вероятно, противоречит определенным правилам полиморфизма.Если мне действительно нужно, я могу скопировать do_x_ten_times () в оба класса B и C и сделать его абстрактным в A .Но мне интересно, есть ли разумный способ повторить этот код.

1 Ответ

3 голосов
/ 16 июня 2019

Вам нужно позвонить self.x() в 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()
...