Я запускаю Python 2.5, поэтому этот вопрос может не распространяться на Python 3. Когда вы создаете иерархию классов алмаза с использованием множественного наследования и создаете объект производного класса, Python делает Right Thing (TM). Он вызывает конструктор для производного класса, а затем его родительские классы, перечисленные слева направо, а затем дедушку. Я знаком с Python MRO; это не мой вопрос. Мне любопытно, как объект, возвращенный из супер, действительно управляет, чтобы сообщать вызовам супер в родительских классах правильный порядок. Рассмотрим этот пример кода:
#!/usr/bin/python
class A(object):
def __init__(self): print "A init"
class B(A):
def __init__(self):
print "B init"
super(B, self).__init__()
class C(A):
def __init__(self):
print "C init"
super(C, self).__init__()
class D(B, C):
def __init__(self):
print "D init"
super(D, self).__init__()
x = D()
Код делает интуитивно понятную вещь, он печатает:
D init
B init
C init
A init
Однако, если вы закомментируете вызов super в функции B init, не вызывается функция A или C init. Это означает, что вызов B в супер так или иначе знает о существовании C в общей иерархии классов. Я знаю, что супер возвращает прокси-объект с перегруженным оператором get, но как объект, возвращаемый супер в определении D init, сообщает существование C объекту, возвращаемому супер в определении B init? Является ли информация о том, что последующие вызовы суперпользователя хранятся на самом объекте? Если да, то почему не супер, а self.super?
Edit: Jekke совершенно справедливо указал, что это не self.super, потому что super является атрибутом класса, а не экземпляром класса. Концептуально это имеет смысл, но на практике супер также не является атрибутом класса! Вы можете проверить это в интерпретаторе, выполнив два класса A и B, где B наследует от A и вызывает dir(B)
. Он не имеет атрибутов super
или __super__
.