Лучший способ получить доступ к методу суперкласса в множественном наследовании - PullRequest
7 голосов
/ 14 сентября 2011
class Animal(object):
    def eat(self):
        print("I eat all")

class C(object):
    def eat(self):
        print("I too eat")

class Wolf(C, Animal):
    def eat(self):
        print("I am Non Veg")
        super(Wolf, self).eat()
        Animal.eat(self)

w = Wolf()
w.eat()

Я изучаю множественное наследование в Python, я хочу получить доступ к Animal и C методу eat из производного класса, используя super метод.

Вызов по умолчанию superвнутри вызовов C метод класса eat, но для вызова Animal метод класса я использовал Animal.eat(self). Мой вопрос в том, как я могу вызвать Animal метод класса, используя super метод.

Ответы [ 4 ]

6 голосов
/ 14 сентября 2011

Если вы хотите использовать нормальное множественное наследование, вам нужно каждый для вызова super, за исключением ровно одного базового класса, который обязан не вызывать super.Наличие двух полностью независимых базовых классов с одним и тем же методом не имеет смысла при использовании теории ООП и не является тем, что Python имеет инструменты для хорошей обработки.

Вы можете увидеть два очевидно независимых независимых базовых классаво многих примерах, но в этих случаях примерным методом обычно является __init__, и единственный базовый класс, не вызывающий суперзвуков для него, - object.

2 голосов
/ 14 сентября 2011

Вы не можете позвонить Animal.eat, используя super. super использует Порядок разрешения методов Python (MRO) , чтобы выяснить, какой класс вызывать, а C затмевает Animal в этом MRO.

В вашем примере super(Wolf, self).eat() имеет тот же эффект, что и C.eat(self). Вызов Animal.eat(self) работает, но только до тех пор, пока граф наследования остается таким же, каким он является в настоящее время.

Необходимость вызова метода, который недоступен из-за MRO, указывает на необходимость улучшения моделирования классов.

1 голос
/ 14 сентября 2011

super используется для поиска в родительских классах.В вашем случае, поскольку вы устанавливаете наследование в порядке C, Animal, предпочтение при поиске метода выглядит следующим образом:

  • первый родительский класс
  • второй родительский класс

Таким образом, super вернет метод ближайшего родителя.

Однако следует отметить, что поиск выполняется в порядке глубины:

>>> class A(object):
...      def t(self):
...          print 'from A'
>>> class B(object):
...      def t(self):
...          print 'from B'
>>> class C(A):
...      pass
>>> class D(C, B):
...      pass
>>> d = D()
>>> d.t()
from A
0 голосов
/ 14 сентября 2011

super() использует Порядок разрешения методов (MRO) , чтобы определить, какой метод суперкласса вызывается.

Лучший способ контролировать, какой метод класса в случае множественного наследования, это вызывать его явно, без использования super().

Или вы можете изменить порядок суперклассов в определении подкласса, чтобы изменить MRO. Это позволяет вам продолжать использовать super(), но жертвует некоторой читабельностью, IMO.

Пример использования super():

class Wolf(C, Animal):
    def eat(self):
        # C.eat() comes first in the MRO
        super(Wolf, self).eat()

Versus:

class Wolf(Animal, C):
    def eat(self):
        # Animal.eat() comes first in the MRO
        super(Wolf, self).eat()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...