CodeGym /Cursos /Python SELF PT /Ordem de Resolução de Métodos (MRO)

Ordem de Resolução de Métodos (MRO)

Python SELF PT
Nível 16, Lição 5
Disponível

11.1 Method Resolution Order

A Ordem de Resolução de Métodos (Method Resolution Order, MRO) determina a sequência em que o Python busca métodos e atributos na hierarquia de classes. Isso é especialmente importante ao trabalhar com múltipla herança, onde uma classe pode herdar atributos e métodos de várias classes pai.

Basicamente, existe uma ordem fixa e rigorosa (ou melhor, um algoritmo), segundo o qual o Python percorre a árvore de herança das classes. Esse algoritmo garante a correta ordem de busca dos métodos, que pode ser descrita assim:

Algoritmo de Linearização C3

O Algoritmo de Linearização C3 determina o MRO combinando:

  • A própria classe.
  • Lista de classes pai na ordem que são listadas.
  • MRO das classes pai na mesma ordem.

Regras do Algoritmo de Linearização C3

  • Preservar a ordem local dos métodos: se a classe A é mencionada antes da classe B, todos os métodos da classe A devem ser considerados antes dos métodos da classe B.
  • Manter a ordem nas classes pai: se a classe A é pai da classe B, então todos os métodos da classe A devem ser considerados antes dos métodos da classe B.
  • Levar em conta a ordem de herança: se a classe C é pai de duas ou mais classes, a ordem dos métodos da classe C deve ser mantida no MRO de todas essas classes.

Passos do algoritmo:

Passo 1. Começamos com a própria classe:

Sempre começamos com a própria classe onde o método é chamado.

Passo 2. Adicionamos as classes base na ordem que são listadas:

Depois da classe atual, verificamos as classes base na ordem em que são especificadas na herança.

Passo 3. Percorremos as classes pai:

Procuramos campos e métodos lá.

Passo 4. Combinamos o MRO das classes pai:

Se a mesma classe base for herdada através de múltiplos caminhos, ela será verificada apenas uma vez e na ordem correta (todas as outras vezes será pulada).

Para aqueles que já estão familiarizados com o assunto "Algoritmos e Estruturas de Dados", isso é busca em profundidade e não em largura.

11.2 Verificando o MRO

No Python, é possível verificar a ordem de busca de métodos e campos da classe usando o atributo __mro__ ou a função mro().

Exemplo:


class A:
    def method(self):
        print("A")
        
class B(A):
    def method(self):
        print("B")
        
class C(A):
    def method(self):
        print("C")
        
class D(B, C):
    def method(self):
        print("D")
        

# Verificando MRO
print(D.__mro__)
        

A saída será:


(<class '__main__.D'>, 
<class '__main__.B'>, 
<class '__main__.C'>,
<class '__main__.A'>,
<class 'object'>)
        

Isso mostra a ordem em que o Python buscará métodos e atributos:

  • D: O Python checa primeiro o método na classe D.
  • B: Depois, o Python checa o método na classe B (primeira classe pai).
  • C: Se o método não for encontrado na classe B, o Python checa o método na classe C (segunda classe pai).
  • A: Se o método não for encontrado nas classes B e C, o Python verifica o método na classe A.
  • object: Finalmente, o Python verifica o método na classe base object.

11.3 Usando super() com MRO

A função super() segue o MRO para chamar métodos de classes pai na ordem correta. Considere o exemplo de uso de super():

class A:
    def method(self):
        print("A")
        super().method()
        
class B(A):
    def method(self):
        print("B")
        super().method()
        
class C(A):
    def method(self):
        print("C")
        super().method()
        
class D(B, C):
    def method(self):
        print("D")
        super().method()
        
        
d = D()
d.method()
        

A saída será a seguinte:


D
B
C
A
        

Ordem de Busca (MRO)

1. Chamada do método method da classe D:

  • O Python checa primeiro o método na classe D e o encontra lá.
  • O método D.method() é executado e imprime "D".
  • Então, super().method() é chamado, que segue o MRO para chamar o próximo método.

2. Chamada do método method da classe B:

  • De acordo com o MRO, a próxima classe após D é B.
  • O método B.method() é executado e imprime "B".
  • Então, super().method() é chamado, que segue o MRO para chamar o próximo método.

3. Chamada do método method da classe C:

  • A próxima classe no MRO após B é C.
  • O método C.method() é executado e imprime "C".
  • Então, super().method() é chamado, que segue o MRO para chamar o próximo método.

4. Chamada do método method da classe A:

  • A próxima classe no MRO após C é A.
  • O método A.method() é executado e imprime "A".
  • Então, super().method() é chamado, mas como A não tem métodos pai de method (além de object), a chamada termina sem mais ações.
2
Tarefa
Python SELF PT, nível 16, lição 5
Bloqueado
Uso de super() e MRO
Uso de super() e MRO
2
Tarefa
Python SELF PT, nível 16, lição 5
Bloqueado
Sobrescrita de método
Sobrescrita de método
1
Pesquisa/teste
Herança, nível 16, lição 5
Indisponível
Herança
Herança
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION