Это подробно и с достаточным количеством подробностей сам Гвидо в своем сообщении в блоге Порядок разрешения методов (включая две более ранние попытки).
В вашем примере Third()
вызоветFirst.__init__
.Python ищет каждый атрибут в родительских классах, поскольку они перечислены слева направо.В этом случае мы ищем __init__
.Итак, если вы определите
class Third(First, Second):
...
Python начнет с просмотра First
, а если First
не имеет атрибута, то он будет смотреть на Second
.
Эта ситуация становится более сложной, когда наследование начинает пересекать пути (например, если First
унаследовано от Second
).Прочитайте ссылку выше для получения более подробной информации, но, в двух словах, Python будет пытаться поддерживать порядок, в котором каждый класс появляется в списке наследования, начиная с самого дочернего класса.
Так, например, еслиу вас было:
class First(object):
def __init__(self):
print "first"
class Second(First):
def __init__(self):
print "second"
class Third(First):
def __init__(self):
print "third"
class Fourth(Second, Third):
def __init__(self):
super(Fourth, self).__init__()
print "that's it"
MRO было бы [Fourth, Second, Third, First].
Кстати: если Python не может найти порядок разрешения связного метода, он вызовет исключение, вместо того, чтобы отступатьк поведению, которое может удивить пользователя.
Отредактировано, чтобы добавить пример неоднозначного MRO:
class First(object):
def __init__(self):
print "first"
class Second(First):
def __init__(self):
print "second"
class Third(First, Second):
def __init__(self):
print "third"
Должно ли Third
MRO быть [First, Second]
или [Second, First]
?Нет очевидных ожиданий, и Python выдаст ошибку:
TypeError: Error when calling the metaclass bases
Cannot create a consistent method resolution order (MRO) for bases Second, First
Edit: Я вижу, как некоторые люди утверждают, что в приведенных выше примерах отсутствуют вызовы super()
, поэтому позвольте мне объяснить:смысл примеров в том, чтобы показать, как строится MRO.Они не предназначены для печати "first \ nsecond \ третий" или что-то еще.Вы можете - и, конечно, должны поиграться с этим примером, добавить вызовы super()
, посмотреть, что произойдет, и глубже понять модель наследования Python.Но моя цель здесь состоит в том, чтобы сделать это простым и показать, как строится MRO.И он построен, как я объяснил:
>>> Fourth.__mro__
(<class '__main__.Fourth'>,
<class '__main__.Second'>, <class '__main__.Third'>,
<class '__main__.First'>,
<type 'object'>)