Про це детально роз'яснюється з досить розумною деталізацією самого Гвідо в своєму дописі про блог Методичне рішення (включаючи дві попередні спроби).
У вашому прикладі 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"
МРО буде [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
бути МРО [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()
дзвінків, тому дозвольте мені пояснити: Суть прикладів - показати, як будується МРО. Вони не призначені для друку "першої \ n секунди \ третьої" чи будь-чого іншого. Можна, і, звичайно, потрібно пограти з прикладом, додавати super()
дзвінки, бачити, що відбувається, і глибше розуміти модель успадкування Python. Але моя мета тут - зробити це просто і показати, як будується МРО. І він побудований так, як я пояснив:
>>> Fourth.__mro__
(<class '__main__.Fourth'>,
<class '__main__.Second'>, <class '__main__.Third'>,
<class '__main__.First'>,
<type 'object'>)
super()
будь-яка користь. Я б не рекомендував використовувати його з класами з використанням лінійного успадкування, де це просто марно накладні витрати.