Это подробно описано с достаточным количеством подробностей самим Гвидо в его посте « Постановление о разрешении метода» (включая две более ранние попытки).
В вашем примере 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
Редактировать: Я вижу, как несколько человек утверждают, что в приведенных выше примерах отсутствуют super()вызовы, поэтому позвольте мне объяснить: цель примеров - показать, как строится MRO. Они не предназначены для печати "первая \ третья \ третья" или что-то еще. Вы можете - и, конечно, должны поиграться с этим примером, добавить super()вызовы, посмотреть, что происходит, и глубже понять модель наследования Python. Но моя цель здесь состоит в том, чтобы сделать это простым и показать, как строится MRO. И это построено, как я объяснил:
>>> Fourth.__mro__
(<class '__main__.Fourth'>,
<class '__main__.Second'>, <class '__main__.Third'>,
<class '__main__.First'>,
<type 'object'>)
super()есть какое-либо применение. Я не рекомендовал бы использовать это с классами, использующими линейное наследование, где это просто бесполезные накладные расходы.