Использование super () в множественном и многоуровневом наследовании - PullRequest
0 голосов
/ 24 марта 2020

Я новичок в множественном и многоуровневом наследовании. Я пытался выполнить пример:

class First(object):
    def __init__(self):
        super().__init__()
        print("first")

class Second(object):
    def __init__(self):
        super().__init__()
        print("second")

class Third(First, Second):
    def __init__(self):
        super().__init__()
        print("third")
Third()

Вывод, который я получил:

second
first
third
<__main__.Third at 0x21bbaf2fc88>

Может кто-нибудь объяснить, пожалуйста, причину этого вывода? Я ожидал, что результат будет:

first
second
third

Так как __init __ () третьего вызовет __init __ () класса First (потому что он первый в списке родителей), который сначала напечатает __init __ второго класса ( ) и, наконец, __init __ () третьего класса.

MRO печатает то, что я ожидал.

print(Third.__mro__)

печатает

(__main__.Third, __main__.First, __main__.Second, object)

Ответы [ 2 ]

0 голосов
/ 24 марта 2020

Кажется, это просто артефакт, когда вы печатаете в __init__. Ваш текущий код печатает после , он вызывает super().__init__, и поэтому иерархия наследования печатается в обратном порядке. Если вы печатаете перед супер вызовом, он будет в том же порядке, что и MRO. Возможно, было бы проще понять, если бы вы печатали в обоих направлениях:

class First(object):
    def __init__(self):
        print("first (top)")
        super().__init__()
        print("first (bottom)")

class Second(object):
    def __init__(self):
        print("second (top)")
        super().__init__()
        print("second (bottom)")

class Third(First, Second):
    def __init__(self):
        print("third (top)")
        super().__init__()
        print("third (bottom)")

Теперь вывод Third() должен быть:

third (top)
first (top)
second (top)
second (bottom)
first (bottom)
third (bottom)

Вывод, который вы видите, это <__main__.Third ...> печатается не вашим кодом, а интерактивной оболочкой. Это результат вызова Third, экземпляра класса. Если бы вы сделали instance = Third(), вы бы этого не увидели, так как значение будет сохранено в переменной, а не распечатано. REPL (чтение Eval Print L oop) выполняется только тогда, когда Python запускается в интерактивном режиме, он не будет выполнять дополнительную печать в модулях, которые вы импортируете или запускаете как скрипт.

0 голосов
/ 24 марта 2020

Если вы делаете super().__init__() до , вы звоните print(xxx), показанный порядок правильный.

Если вы хотите, чтобы порядок отображался на вкладке «исключено», вы можете поменять местами каждый print(xxx) с super().__init__(), и это все исправит.

Код:

class First(object):
    def __init__(self):
        print("first")
        super().__init__()

class Second(object):
    def __init__(self):
        print("second")
        super().__init__()

class Third(First, Second):
    def __init__(self):
        print("third")            
        super().__init__()
Third()
...