Правильное использование super()
довольно тонкое и требует некоторой осторожности, если не все методы сотрудничества имеют одинаковую подпись. Обычный шаблон для __init__()
методов следующий:
class A(object):
def __init__(self, param_a, **kwargs):
self.param_a = param_a
super(A, self).__init__(**kwargs)
class B(A):
def __init__(self, param_b, **kwargs):
self.param_b = param_b
super(B, self).__init__(**kwargs)
class C(A):
def __init__(self, param_c, **kwargs):
self.param_c = param_c
super(C, self).__init__(**kwargs)
class D(B, C):
def __init__(self, param_d, **kwargs):
self.param_d = param_d
super(D, self).__init__(**kwargs)
d = D(param_a=1, param_b=2, param_c=3, param_d=4)
Обратите внимание, что для этого необходимо, чтобы все методы сотрудничали, и чтобы все методы имели несколько совместимую подпись, чтобы гарантировать, что не имеет значения, в какой момент вызывается метод.
Конструкторы встроенных типов не имеют сигнатур конструктора, позволяющих участвовать в такой совместной работе. Даже если бы они вызвали super().__init__()
, это было бы довольно бесполезно, если бы все сигнатуры конструктора не были объединены. Таким образом, в конце концов вы правы - они не подходят для участия в совместных вызовах конструктора.
super()
можно использовать только в том случае, если либо все методы сотрудничества имеют одинаковую подпись (например, __setattr__()
), либо если вы используете вышеупомянутый (или аналогичный) шаблон. Однако использование super()
- не единственный шаблон для вызова методов базового класса. Если в шаблоне множественного наследования нет «алмазов», вы можете использовать явные вызовы базового класса, например B.__init__(self, param_a)
. Классы с несколькими базовыми классами просто вызывают несколько конструкторов. Даже если есть алмазы, вы можете иногда использовать явные вызовы, если вы позаботитесь о том, чтобы __init__()
можно было вызывать несколько раз без вреда.
Если вы все равно хотите использовать super()
для конструкторов, вам действительно не следует использовать подклассы встроенных типов (за исключением object
) в нескольких иерархиях наследования. Некоторое дальнейшее чтение: