Я пытаюсь написать среду плагинов, в которой мне нужно выполнять множественное наследование для неизвестного количества классов. Поэтому я решил использовать создание класса типа:
class A(object):
def __init__(self,s):
self.a = "a"
def testA(self,x):
print(x)
class B(object):
def __init__(self,s):
self.b = "b"
def testA(self,x):
print(x)
C = type('C', (A,B), {})
x= C("test")
print x.b
Когда я запускаю приведенный выше код, я получаю сообщение об ошибке:
AttributeError: 'C' object has no attribute 'b'
Это связано с тем, что при инициализации экземпляра для класса C выполняется только в этом для класса A. Мой вопрос в том, как я могу заставить класс C иметь как в этом для класса A, так и в этом для класса B для запуска при инициализации экземпляра класса C. Я понимаю, что если бы у меня был класс C, как показано ниже, он работал бы:
class C(A,B):
def __init__(self,s):
A.__init__(self,s)
B.__init__(self,s)
Однако, учитывая, что мне нужен динамический список унаследованных классов, это не сработает.






Похоже, вы используете python 2, поэтому я использую этот старый синтаксис python 2 super(), в котором вам нужно указать класс и экземпляр, хотя он также будет работать в python 3. В python 3 вы также можете использовать более короткую форму super() без параметров.
Для работы множественного наследования важно, чтобы подпись класса «дедушка-дедушка» __init__ соответствовала сигнатуре всех братьев и сестер для этого метода. Для этого определите общий родительский класс (MyParent в этом примере), чей __init__ имеет тот же список параметров, что и все дочерние элементы. Он позаботится о вызове object__init__, который не принимает никаких параметров для нас.
from __future__ import print_function
class MyParent(object):
def __init__(self, s):
super(MyParent, self).__init__()
class A(MyParent):
def __init__(self, s):
self.a = "a"
super(A, self).__init__(s)
def testA(self, x):
print(x)
class B(MyParent):
def __init__(self, s):
self.b = "b"
super(B, self).__init__(s)
def testA(self,x):
print(x)
C = type('C', (A, B), {})
x = C("test")
print(x.b)
Вы можете определить столько дочерних элементов для MyParent, сколько захотите, и тогда будут вызваны все методы __init__, при условии, что вы правильно использовали super().
Спасибо за ваш ответ. Не могли бы вы рассказать, почему в инициализации MyParent есть супер?
он вызывает object.__init__ ... который ничего не делает, но вы не должны полагаться на то, что он ничего не делает. Это инициализация родительского класса, поэтому вы всегда должны называть его
Используйте
super(), который предназначен именно для этого сценария.