A herança é útil, mas você pode desbloquear todo o seu potencial reutilizando o código das classes base.

Principais conclusões

  • A função super() do Python permite chamar métodos de superclasse de uma subclasse, facilitando a implementação de herança e substituição de método.
  • A função super() está intimamente relacionada à Ordem de Resolução de Método (MRO) em Python, que determina a ordem em que as classes ancestrais são pesquisadas em busca de métodos ou atributos.
  • Usar super() em construtores de classe é uma prática comum para inicializar atributos comuns na classe pai e outros mais específicos na classe filha. Deixar de usar super() pode levar a consequências indesejadas, como falta de inicializações de atributos.

Um dos principais recursos do Python é seu paradigma OOP, que você pode usar para modelar entidades do mundo real e seus relacionamentos.

Ao trabalhar com classes Python, você frequentemente usará herança e substituirá atributos ou métodos de uma superclasse. Python fornece um super() função que permite chamar os métodos da superclasse a partir da subclasse.

instagram viewer

O que é super() e por que você precisa dele?

Usando herança, você pode criar uma nova classe Python que herda os recursos de uma classe existente. Você também pode substituir métodos da superclasse na subclasse, fornecendo implementações alternativas. No entanto, você pode querer usar a nova funcionalidade além da antiga, em vez de substituí-la. Nesse caso, super() é útil.

Você pode usar o super() função para acessar atributos da superclasse e invocar métodos da superclasse. Super é essencial para programação orientada a objetos porque facilita a implementação de herança e substituição de métodos.

Como funciona super()?

Internamente, super() está intimamente relacionado com o Ordem de resolução de método (MRO) em Python, que o algoritmo de linearização C3 determina.

Veja como super() funciona:

  1. Determinar a classe e instância atuais: Quando Você ligar super() dentro de um método de uma subclasse, o Python descobre automaticamente a classe atual (a classe que contém o método que chamou super()) e a instância dessa classe (ou seja, auto).
  2. Determine a superclasse: super() recebe dois argumentos – a classe atual e a instância – que você não precisa passar explicitamente. Ele usa essas informações para determinar a superclasse à qual delegar a chamada do método. Isso é feito examinando a hierarquia de classes e o MRO.
  3. Invoque o método na Superclasse: Uma vez determinada a superclasse, super() permite que você chame seus métodos como se os estivesse chamando diretamente da subclasse. Isso permite estender ou substituir métodos enquanto ainda usa a implementação original da superclasse.

Usando super() em um construtor de classe

Usando super() em um construtor de classe é uma prática comum, já que muitas vezes você desejará inicializar atributos comuns na classe pai e atributos mais específicos na classe filha.

Para demonstrar isso, definir uma classe Python, Pai, que um Filho classe herda de:

classFather:
def__init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name

classSon(Father):
def__init__(self, first_name, last_name, age, hobby):
# Call the parent class constructor (Father)
super().__init__(first_name, last_name)

self.age = age
self.hobby = hobby

defget_info(self):
returnf"Son's Name: {self.first_name}{self.last_name}, \
Son's Age: {self.age}, Son's Hobby: {self.hobby}"

# Create an instance of the Son class
son = Son("Pius", "Effiong", 25, "Playing Guitar")

# Access attributes
print(son.get_info())

Dentro de Filho construtor, a chamada para super().init() invoca o Pai construtor de classe, passando-o primeiro nome e sobrenome como parâmetros. Isto garante que o Pai classe ainda pode definir os atributos de nome corretamente, mesmo em um Filho objeto.

Se você não ligar super() em um construtor de classe, o construtor de sua classe pai não será executado. Isso pode levar a consequências não intencionais, como falta de inicializações de atributos ou configuração incompleta do estado da classe pai:

...
classSon(Father):
def__init__(self, first_name, last_name, age, hobby):
self.age = age
self.hobby = hobby
...

Se você agora tentar ligar para o obter informação método, ele levantará um AtributoError porque o self.first_name e self.last_name atributos não foram inicializados.

Usando super() em métodos de classe

Você pode usar super() em outros métodos, além dos construtores, da mesma maneira. Isso permite estender ou substituir o comportamento do método da superclasse.

classFather:
defspeak(self):
return"Hello from Father"

classSon(Father):
defspeak(self):
# Call the parent class's speak method using super()
parent_greeting = super().speak()
returnf"Hello from Son\n{parent_greeting}"

# Create an instance of the Son class
son = Son()

# Call the speak method of the Son class
son_greeting = son.speak()

print(son_greeting)

O Filho classe herda de Pai e tem seu falar método. O falar método do Filho classe usa super().speak() para ligar para o falar método do Pai aula. Isso permite incluir a mensagem da classe pai enquanto a estende com uma mensagem específica para a classe filha.

Não conseguindo usar super() em um método que substitui outro significa que a funcionalidade presente no método da classe pai não terá efeito. Isso resulta em uma substituição completa do comportamento do método, o que pode levar a um comportamento indesejado.

Compreendendo a ordem de resolução do método

Ordem de resolução de método (MRO) é a ordem em que Python pesquisa classes ancestrais quando você acessa um método ou atributo. O MRO ajuda o Python a determinar qual método chamar quando existem múltiplas hierarquias de herança.

classNigeria():
defculture(self):
print("Nigeria's culture")

classAfrica():
defculture(self):
print("Africa's culture")

Veja o que acontece quando você cria uma instância do Lagos aula e ligue para o cultura método:

  1. Python começa procurando pelo cultura método no Lagos classe em si. Se encontrar, ele chama o método. Caso contrário, passa para a etapa dois.
  2. Se não encontrar o cultura método no Lagos classe, o Python examina as classes base na ordem em que aparecem na definição da classe. Nesse caso, Lagos herda primeiro de África e então de Nigéria. Então, Python irá procurar o cultura método em África primeiro.
  3. Se não encontrar o cultura método no África classe, o Python irá então procurar no Nigéria aula. Esse comportamento continua até atingir o final da hierarquia e gera um erro se não conseguir encontrar o método em nenhuma das superclasses.

A saída mostra a ordem de resolução do método de Lagos, começando da esquerda para a direita.

Armadilhas comuns e práticas recomendadas

Ao trabalhar com super(), existem algumas armadilhas comuns a serem evitadas.

  1. Esteja atento à Ordem de Resolução do Método, especialmente em cenários de herança múltipla. Se você precisar usar herança múltipla complexa, você deve estar familiarizado com o Algoritmo de linearização C3 que o Python usa para determinar o MRO.
  2. Evite dependências circulares na hierarquia de classes, que podem levar a um comportamento imprevisível.
  3. Documente seu código claramente, especialmente ao usar super() em hierarquias de classes complexas, para torná-lo mais compreensível para outros desenvolvedores.

Use super() da maneira certa

Python super() function é um recurso poderoso quando você está trabalhando com herança e substituição de método. Entendendo como super() funciona e seguir as práticas recomendadas permitirá que você crie um código mais sustentável e eficiente em seus projetos Python.