Pergunta

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

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

B()  # output: hello

Em todas as outras línguas que eu já trabalhou com o super construtor é chamado implicitamente.Como invocá-lo em Python?Eu esperaria super(self) mas isto não funciona.

Foi útil?

Solução

super() Retorna um objeto parecido com um pai em aulas de novo estilo:

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

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

B()

Outras dicas

De acordo com as outras respostas, existem várias maneiras de chamar métodos de super classe (incluindo o construtor), no entanto, no Python-3.x, o processo foi simplificado:

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() agora é equivalente a super(<containing classname>, self) conforme os documentos.

Com as aulas de estilo antigo Python 2.x, seria isso:

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

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

Uma maneira é chamar o construtor de A e passar self Como argumento, assim:

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

A vantagem desse estilo é que é muito claro. Ele chama o Inicializador de A. A desvantagem é que ele não lida muito bem com a herança em forma de diamante, já que você pode acabar chamando o Initientar da classe base compartilhada duas vezes.

Outra maneira é usar super (), como outros mostraram. Para uma única elevação, faz basicamente a mesma coisa que permitir que você chame o inicializador do pai.

No entanto, Super () é um pouco mais complicado sob a altura e às vezes pode ser contra-intuitivo em várias situações de herança. No lado positivo, Super () pode ser usado para lidar com a herança em forma de diamante. Se você quiser saber o âmago da questão do que Super () faz, a melhor explicação que encontrei para o modo como Super () funciona aqui (Embora eu não esteja necessariamente endossando as opiniões desse artigo).

Resposta curta

super(DerivedClass, self).__init__()

Resposta longa

O que super() Faz?

É preciso nome de classe especificado, encontra suas classes base (o python permite a herança múltipla) e procura o método (__init__ neste caso) em cada um deles da esquerda para a direita. Assim que encontrar o método disponível, ele o chamará e terminará a pesquisa.

Como faço para chamar o init de todas as classes base?

Acima funciona se você tiver apenas uma classe base. Mas o Python permite a herança múltipla e você pode garantir que todas as classes base sejam inicializadas corretamente. Para fazer isso, você deve ter cada classe base chamada init:

class Base1:
  def __init__():
    super(Base1, self).__init__()

class Base2:
  def __init__():
    super(Base2, self).__init__()

class Derived(Base1, Base2):
  def __init__():
    super(Derived, self).__init__()

E se eu esquecer de ligar para o init para super?

O construtor (__new__) é invocado em uma corrente (como em C ++ e Java). Depois que a instância é criada, apenas o inicializador desta instância (__init__) é chamado, sem nenhuma cadeia implícita para sua superclasse.

Para adicionar apenas um exemplo com parâmetros:

class B(A):
    def __init__(self, x, y, z):
        A.__init__(self, x, y)

Dada uma classe derivada de B, que requer que as variáveis x, y, z para ser definido, e uma superclasse, o que requer x e y para ser definido, você pode chamar o método estático init da superclasse Um com uma referência para a atual subclasse instância (auto) e, em seguida, a lista dos argumentos.

Eu uso a seguinte fórmula que estende as respostas anteriores:

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

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

B()

Dessa forma, você não precisa repetir o nome da classe na chamada para super. Pode ser útil se você estiver codificando um grande número de classes e desejar fazer seu código nos métodos iniciantes independentes do nome da classe.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top