Как вызвать супер конструктор?


class A:
 def __init__(self):
   print "world"

class B(A):
 def __init__(self):
   print "hello"

B()
hello

во всех других языках я работал с супер конструктором вызывается неявно. Как вызвать его в Python? Я бы ожидал super(self) но это не сработает.

5 251

5 ответов:

super() возвращает родительский объект в классах нового стиля:

class A(object):
    def __init__(self):
        print "world"

class B(A):
    def __init__(self):
        print "hello"
        super(B, self).__init__()

B()

в соответствии с другими ответами существует несколько способов вызова методов суперкласса (включая конструктор), однако в Python-3.x процесс был упрощен:

Python-2.x

class A(object):
 def __init__(self):
   print "world"

class B(A):
 def __init__(self):
   print "hello"
   super(B, self).__init__()

Python-3.x

class A(object):
 def __init__(self):
   print("world")

class B(A):
 def __init__(self):
   print("hello")
   super().__init__()

super() теперь эквивалентна super(<containing classname>, self) по состоянию на документы.

С Python 2.x классы старого стиля это было бы так:

class A: 
 def __init__(self): 
   print "world" 

class B(A): 
 def __init__(self): 
   print "hello" 
   A.__init__(self)

один из способов-вызвать конструктор A и передать self в качестве аргумента, например, так:

class B(A):
    def __init__(self):
        A.__init__(self)
        print "hello"

преимущество этого стиля в том, что это очень ясно. Это вызов конструктора. Недостатком является то, что он не очень хорошо обрабатывает ромбовидное наследование, так как вы можете в конечном итоге вызвать конструктор общего базового класса дважды.

другой способ-использовать Super(), как показано. Для одиночного наследования он делает в основном то же самое, что позволяет вам называть родительский конструктор.

тем не менее, super() довольно немного сложнее под капотом и иногда может быть противоинтуитивным в ситуациях множественного наследования. С положительной стороны, super() можно использовать для обработки ромбовидного наследования. Если вы хотите знать, что делает super (), лучшее объяснение, которое я нашел для того, как работает super (), - это здесь (хотя я не обязательно одобряю мнения этой статьи).

Я использую следующую формулу, которая расширяет предыдущие ответы:

class A(object):
 def __init__(self):
   print "world"

class B(A):
 def __init__(self):
   print "hello"
   super(self.__class__, self).__init__()

B()

таким образом, вам не нужно повторять имя класса в вызове супер. Это может пригодиться, если вы кодируете большое количество классов и хотите сделать свой код в методах конструктора независимым от имени класса.