Вызов init для нескольких родительских классов с super?

Возможный дубликат:
Может ли Super справиться с множественным наследованием?

Наследование Python? У меня есть структура класса (ниже), и я хочу, чтобы дочерний класс вызывал __init__ обоих родителей. Это возможно сделать "супер" или это просто ужасная идея?

class Parent1(object):
    def __init__(self):
        self.var1 = 1

class Parent2(object):
    def _init__(self):
        self.var2 = 2

class Child(Parent1, Parent2):
    def __init__(self):
        ## call __init__ of Parent1
        ## call __init__ of Parent2
        ## super(Child, self).__init__()

3 ответа

Решение

Вызов через super не вызывает всех родителей, он вызывает следующую функцию в цепочке MRO. Чтобы это работало правильно, вам нужно использовать super во всех __init__s:

class Parent1(object):
    def __init__(self):
        super(Parent1, self).__init__()
        self.var1 = 1

class Parent2(object):
    def __init__(self):
        super(Parent2, self).__init__()
        self.var2 = 2

class Child(Parent1, Parent2):
    def __init__(self):
        super(Child, self).__init__()

В Python 3 вы можете использовать super() вместо super(type, instance),

Идея super() что вам не нужно называть оба суперкласса __init__() методы отдельно - super() позаботится об этом, при условии, что вы используете его правильно - см. Раймонд Хеттингер "Супер () Python считается супер!" для объяснения.

Тем не менее, я часто нахожу недостатки super() для звонков конструктора перевешивают преимущества. Например, все ваши конструкторы должны предоставить дополнительный **kwargs аргумент, все классы должны сотрудничать, не сотрудничающие внешние классы нуждаются в обертке, вы должны заботиться о том, чтобы каждое имя параметра конструктора было уникальным для всех ваших классов и т. д.

Поэтому чаще всего я думаю, что проще назвать методы базового класса, которые вы хотите вызвать для вызовов конструктора:

class Child(Parent1, Parent2):
    def __init__(self):
        Parent1.__init__(self)
        Parent2.__init__(self)

Я использую super() для функций, которые имеют гарантированный прототип, например __getattr__(), хоть. В этих случаях нет недостатков.

Вы можете просто позвонить им напрямую с Parent.__init__(self):

class Parent1(object):
    def __init__(self):
        self.var1 = 1

class Parent2(object):
    def __init__(self):
        self.var2 = 2

class Child(Parent1, Parent2):
    def __init__(self):
        Parent1.__init__(self)
        Parent2.__init__(self)
        print(self.var1, self.var2)
Другие вопросы по тегам