Вызов 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)