Что такое класс sibling в Python?

документация Python 2 говорит, что super () функции "возвращает прокси-объект, который делегирует вызовы методов родителя или отпрыска класс тип."

вопросы:

  1. что такое класс sibling в Python?
  2. как делегировать вызов метода классу sibling?

Я предполагал, что брат для данного класса является классом, который наследуется от одного и того же родителя. Я подготовил следующий код, чтобы увидеть, как вызов метода может быть делегирован родному брату, но это не сработало. Что я делаю или понимаю неправильно?

class ClassA(object):
    def MethodA(self):
        print "MethodA of ClassA"

class ClassB(ClassA):
    def MethodB(self):
        print "MethodB of ClassB"

class ClassC(ClassA):
    def MethodA(self):
        super(ClassC, self).MethodA()

    def MethodB(self):
        super(ClassC, self).MethodB()

if __name__ == '__main__':
    ClassC().MethodA() # Works as expected

    # Fail while trying to delegate method to a sibling.
    ClassC().MethodB() # AttirbuteError: 'super' object has no attribute 'MethodB'

2 ответов


после некоторых дальнейших исследований и чтение Python супер () считается супер! статьи я пришел к следующим выводам:

  1. класс братьев и сестер - это то, о чем я думал. Это класс, который наследуется от одного и того же родителя. Это определение документации Python, которое сбило меня с курса. Кажется, что когда документация Python говорит делегирует вызовы метода родительскому или сестринскому классу значит в родитель или родной брат родителя, который также является базовым классом данного ребенка. То есть алмазное наследство должно иметь место.

  2. super() функция делегирует вызов метода a родителей!--22--> класс sibling автоматически основанный на MRO (заказе разрешения метода).

вот интересный случай, который я нашел во время экспериментов с super() функция:

class Class0(object):
    def MethodA(self):
        print("MethodA of Class0")

class ClassA(Class0):
    def MethodA(self):
        super(ClassA, self).MethodA()
        print("MethodA of ClassA")

class ClassB(Class0):
    def MethodA(self):
        print("MethodA of ClassB")

class ClassC(ClassA, ClassB):
    def MethodA(self):
        super(ClassC, self).MethodA()

if __name__ == '__main__':
    ClassC().MethodA()

код будет печатать

MethodA of ClassB
MethodA of ClassA

если вы а мне интересно, почему что и methoda из Класс0 никогда не печатается, вот объяснение, как я его понимаю. MRO ClassC как напечатано с print(ClassC.__mro__) is

(<class '__main__.ClassC'>, <class '__main__.ClassA'>, <class '__main__.ClassB'>, <class '__main__.Class0'>, <class 'object'>).

теперь, если вы будете следовать MRO, функция super() MethodA() ClassC вызовет MethodA() ClassA, который перед печатью вызовет MethodA () classB (так как он следующий в MRO). И MethodA () ClassB в свою очередь будет просто печатать и выходить, так как он не использует функцию super() чтобы делегировать вызов метода далее по цепочке MRO.


отпрыск-это класс с тем же родителем, как вы и подозревали. Дело, которое вы упускаете, это super может вызвать метод sibling если сам этот класс умножается, наследуемый от:

class A(object):
  def something(self):
    print("A")
class B(A):
  def something(self):
    print("B")
class C(A):
  def something(self):
    print("C, about to call super()")
    super(C, self).something()
class D(C, B):
  def something(self):
    super(D, self).something()

>>> D().something()
C, about to call super()
B

на C, мы назвали super(), но у нас есть B - какой-то брат, не родитель, а не родитель брата, но фактический прямой брат C.