31
Python / Re: Вызов конструкторов родителей при множественном наследовании
« : Марта 30, 2019, 11:04:41 am »
В python если вы в конструкторе не переопределяете конструктор вручную, будет автоматически вызван конструктор родителя первой ветки наследования. И далее согласно последовательности __mro__. Единственное, что может вам помешать вызвать конструктор родителя - это его переопределение в классе-предке без вызова конструктора-предка, например:
выведет:
то получим ошибку:
Если же переопределить грамотно:
то все конструкторы вызовутся по порядку без ошибок.
Так же для 2.7 важно, чтобы все объекты в цепочке mro были наследованы от object - т.е. их классы были типами, а не экземплярами classobj. О чем я говорю:
Наследование от такого класса не будет вызывать его конструктор, т.е. наследует только атрибуты класса - все методы и поля класса, но не экземпляра. Это тоже важный паттерн
Код: [Выделить]
class A(object): pass
class B(object):
def __init__(self):
self.b = 1
print "bbbbbbbbbbb"
class C(A,B):
def __init__(self):
super(C,self).__init__()
print "cccccccccccc"
#print self.a
print self.b
def main():
c = C()
выведет:
Цитата:
bbbbbbbbbbbНо если мы переопределим конструктор в A без вызова super:
cccccccccccc
1
Код: [Выделить]
class A(object):
def __init__(self):
pass
то получим ошибку:
Цитата:
AttributeError: 'C' object has no attribute 'b'
Если же переопределить грамотно:
Код: [Выделить]
class A(object):
def __init__(self):
super(A,self).__init__()
print "AAAAAAAAAAAAA"
то все конструкторы вызовутся по порядку без ошибок.
Так же для 2.7 важно, чтобы все объекты в цепочке mro были наследованы от object - т.е. их классы были типами, а не экземплярами classobj. О чем я говорю:
Код: [Выделить]
class B:
def __init__(self):
self.b = 1
print "BBBBBBBBBBBB"
Наследование от такого класса не будет вызывать его конструктор, т.е. наследует только атрибуты класса - все методы и поля класса, но не экземпляра. Это тоже важный паттерн