Динамическое множественное наследование python __init__

Я пытаюсь написать среду плагинов, в которой мне нужно выполнять множественное наследование для неизвестного количества классов. Поэтому я решил использовать создание класса типа:

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)

Однако, учитывая, что мне нужен динамический список унаследованных классов, это не сработает.

Используйте super(), который предназначен именно для этого сценария.

kindall 20.04.2018 19:08
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
273
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Похоже, вы используете 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 есть супер?

user1763510 20.04.2018 19:36

он вызывает object.__init__ ... который ничего не делает, но вы не должны полагаться на то, что он ничего не делает. Это инициализация родительского класса, поэтому вы всегда должны называть его

nosklo 20.04.2018 19:45

Другие вопросы по теме