Вызов метода родительского класса, родительский метод, а не метод дочернего класса - PullRequest
1 голос
/ 11 мая 2019

Есть ли способ для метода дочернего класса, чтобы родитель не вызывал другой дочерний метод, а вместо этого вызывал метод родителя?

Вот пример кода, на который я ссылаюсь:

class A:
    def f(self):
        return 'Af'

    def ff(self, var):
        return var + 'ff ' + self.f()

class B(A):
    def f(self):
        return 'Bf'

    def ff(self):
        return super().ff('B')

print(B().ff())

Выход Bff Bf
Я хочу, чтобы это было: Bff Af

Другими словами, когда B.f() вызывается, я бы хотел перенаправить вызов на A.f(), если вызывающий класс A.
И если вызывающий класс - B, тогда звоните B.f().

Возможно ли это?

Ответы [ 2 ]

1 голос
/ 11 мая 2019

Проблема в том, что вы не разработали A для наследования.Чтобы переопределение методов работало корректно и без непредсказуемых побочных эффектов, вам необходимо тщательно продумать и документ , какие методы зависят от других методов.

Кроме того, у вас есть серьезное нарушение подстановки Лискова втот факт, что B.ff принимает 0 аргументов, когда A.ff принимает один.

У вас есть три основных варианта здесь.Вместо этого нужно использовать композицию:

class B:
    def __init__(self):
        self.a = A()
    def f(self):
        return 'Bf'
    def ff(self):
        return self.a.ff('B')

Теперь B.f не влияет ни на один класс ff.Учитывая несоответствие A.ff и B.ff подписей, наличие B наследования от A, вероятно, является плохой идеей, даже если вы очистите A для лучшей поддержки наследования.

Вариант 2 - решитьчто f является крючком для настройки ff.В этом случае вы сохраняете текущую реализацию и поведение A, а если дочерние классы хотят настроить ff отдельно, они должны переопределить это таким образом, который не зависит от A.ff:

class B(A):
    def f(self):
        return 'Bf'
    def ff(self):
        return 'Bff ' + super().f()

Вариант 3 - решить, что переопределение f не должно влиять на ff.В этом случае A.ff необходимо вызвать A.f таким образом, чтобы на него не влияли переопределения.Например, A.ff может вызвать f как A.f вместо self.f:

class A:
    def f(self):
        return 'Af'

    def ff(self, var):
        return var + 'ff ' + A.f(self)

Тогда ваш существующий B будет работать, как предполагалось.Этот вариант, вероятно, занял второе место после варианта 1.

0 голосов
/ 11 мая 2019

Вы можете легко сделать это, не используя наследование (и вместо этого используйте композицию):

class A:
    def f(self):
        return 'Af'

    def ff(self, var):
        return var + 'ff ' + self.f()

class B:
    def __init__(self):
        self.a = A()

    def f(self):
        return 'Bf'

    def ff(self):
        return self.a.ff('B')

print(B().ff())

Вывод:

Bff Af
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...