Ответ 1
Правильное использование 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
) в нескольких иерархиях бездействия. Дальнейшее чтение:
- Raymond Hettinger Pythons super() считается супер!
- James Knight Python Super отлично, но вы не можете его использовать