происходят вызовы, они эффективно повторяют этот список.
ользую Python 2.5, поэтому этот вопрос может не относиться к Python 3. Когда вы создаете иерархию класса diamond с использованием множественного наследования и создаете объект самого производного класса, Python делает правильную вещь (TM). Он вызывает конструктор для самого производного класса, затем его родительские классы, перечисленные слева направо, затем прародитель. Я знаком с питономMRO; это не мой вопрос. Мне любопытно, как объекту, возвращаемому из super, действительно удается передать вызовы super в родительских классах в правильном порядке. Рассмотрим этот пример кода:
#!/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, не вызывается ни функция инициализации A, ни C. Это означает, что вызов B в super каким-то образом осознает существование C в общей иерархии классов. Я знаю, что super возвращает прокси-объект с перегруженным оператором get, но как объект, возвращенный super в определении init D, сообщает о существовании C объекту, возвращенному super в определении init B? Хранится ли информация о последующих вызовах супериспользования на самом объекте? Если так, то почему не супер вместо self.super?
Редактировать: Джекке совершенно справедливо указал, что это не self.super, потому что super является атрибутом класса, а не экземпляром класса. Концептуально это имеет смысл, но на практике супер не является атрибутом класса! Вы можете проверить это в интерпретаторе, сделав два класса A и B, где B наследуется от A, и вызвавdir(B)
, Не имеетsuper
или же__super__
атрибутов.