Как многократное наследование работает с аргументами super () и разными __init __ ()?

Я просто погружаюсь в более продвинутые темы python (ну, по крайней мере, продвинулся ко мне). Теперь я читаю о множественном наследовании и о том, как вы можете использовать super (). Я более или менее понимаю, как используется суперфункция, но (1) Что не так с тем, чтобы делать это так :

class First(object): def __init__(self): print "first" class Second(object): def __init__(self): print "second" class Third(First, Second): def __init__(self): First.__init__(self) Second.__init__(self) print "that's it" 

На супер (), статья Андрея Кучлинга о бородах Python говорит:

использование super () также будет правильным, если класс Derived наследуется от нескольких базовых классов, а некоторые или все из них имеют методы init

Поэтому я переписал приведенный выше пример следующим образом:

 class First(object): def __init__(self): print "first" class Second(object): def __init__(self): print "second" class Third(First, Second): def __init__(self): super(Third, self).__init__(self) print "that's it" 

Это, однако, запускает только первый init, который он может найти, который находится в First . (2) Можно ли использовать super() для запуска как init, так и First и Second , и если да, то как? Запуск super(Third, self).__init__(self) дважды запускает First. init () дважды ..

Чтобы добавить еще некоторую путаницу. Что делать, если функции init () унаследованных классов принимают разные аргументы. Например, что, если бы у меня было что-то вроде этого:

 class First(object): def __init__(self, x): print "first" class Second(object): def __init__(self, y, z): print "second" class Third(First, Second): def __init__(self, x, y, z): First.__init__(self, x) Second.__init__(self, y, z) print "that's it" 

(3) Как я могу предоставить соответствующие аргументы различным функциям init унаследованных классов с помощью функции super ()?

Все советы приветствуются!

пс. Поскольку у меня есть несколько вопросов, я сделал их смелыми и пронумеровал их.

2 Solutions collect form web for “Как многократное наследование работает с аргументами super () и разными __init __ ()?”

Для вопроса 2 вам нужно вызвать super в каждом классе:

 class First(object): def __init__(self): super(First, self).__init__() print "first" class Second(object): def __init__(self): super(Second, self).__init__() print "second" class Third(First, Second): def __init__(self): super(Third, self).__init__() print "that's it" 

В вопросе 3, который не может быть выполнен, ваш метод должен иметь одну и ту же подпись. Но вы можете просто игнорировать некоторые параметры в родительских кланах или использовать аргументы ключевых слов.

1) Нет ничего плохого в том, что вы сделали в 1, если вы хотите использовать атрибуты из базового класса, тогда вам нужно вызвать базовый класс init () или даже если ur использует методы из базового класса, который использует атрибуты своего собственного класса, тогда вы должны вызвать baseclass init ()

2) Вы не можете использовать super для запуска обоих init из First и Second, потому что python использует MRO (порядок разрешения метода)

см. следующий код, это алмазная иерархия

 class A(object): def __init__(self): self.a = 'a' print self.a class B(A): def __init__(self): self.b = 'b' print self.b class C(A): def __init__(self): self.c = 'c' print self.c class D(B,C): def __init__(self): self.d = 'd' print self.d super(D, self).__init__() d = D() print D.mro() 

Он печатает:

 d b [<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>] 

MRO питона будет D, B, C, A

если B не имеет метода init, то он идет для C.

3) Вы не можете все это сделать, чтобы иметь такую ​​же подпись.

  • Методы Python: значения параметров по умолчанию оцениваются ONCE
  • Как работает super () на Python в общем случае?
  • Как «супер» Python поступает правильно?
  • Явная передача Self при вызове __init__ супер класса в python
  • Использование super () в вложенных классах
  • Как избежать бесконечной рекурсии с помощью super ()?
  • Python super () аргументы: почему бы не super (obj)?
  • super () вызывает «TypeError: должен быть тип, а не classobj» для класса нового стиля
  • Неявно вызывать инициализатор родительского класса
  • Объект 'super' не имеет атрибута '__eq__'
  • python: кооперативный суперкол __getattr__
  • Python - лучший язык программирования в мире.