logo

Ordem de resolução de métodos em Python

Neste tutorial, aprenderemos sobre a ordem de resolução do método, também conhecida como MRO. É um conceito essencial de herança Python.

A ordem de resolução do método descreve o caminho de pesquisa da classe que Pitão usa para obter o método apropriado em classes que contêm a herança múltipla.

Introdução

Como sabemos, uma classe que é herdada é chamada de Subclasse ou Classe Pai, enquanto a classe que herda é conhecida como classe filha ou subclasse. Na herança múltipla, uma classe pode consistir em muitas funções, portanto a técnica de ordem de resolução de método é usada para pesquisar a ordem em que a classe base é executada.

Em palavras simples - 'O método ou atributos são explorados na classe atual, se o método não estiver presente na classe atual, a pesquisa passa para as classes pai e assim por diante'. Este é um exemplo de pesquisa em profundidade.

Ele desempenha um papel essencial na herança múltipla, onde o mesmo método pode ser encontrado em múltiplas superclasses.

Para entendê-lo melhor, vamos ver como podemos usá-lo.

Exemplo -

 class A: def myname(self): print('I am a class A') class B(A): def myname(self): print('I am a class B') class C(A): def myname(self): print('I am a class C') c = C() print(c.myname()) 

Saída:

 I am a class C 

Explicação -

data atual em java

Existe uma herança múltipla no código acima. Definimos três classes chamadas A, B e C, e essas classes têm o mesmo nome de método chamado o meu nome(). Criamos uma classe de objeto C. O objeto invocou a classe C, não a classe, enquanto a classe C herdou o método da classe A.

A ordem seguida no código acima é classe B -> classe A. Esta técnica é conhecida como MRO (ordem de resolução de método).

Vamos entender outro exemplo de herança múltipla.

10 de 100,00

Exemplo -

 class A: def myname(self): print(' I am a class A') class B(A): def myname(self): print(' I am a class B') class C(A): def myname(self): print('I am a class C') # classes ordering class D(B, C): pass d = D() d.myname() 

Saída:

 I am a class B 

Explicação -

No código acima, criamos outra classe D sem definir os atributos de classe que herdaram as classes B e C. Quando invocamos o método o meu nome(), ele vai para a classe D e procura o o meu nome( ) função. Mas a classe D não possui nenhuma declaração. Portanto, a pesquisa é transferida para a classe B, obtém o o meu nome() função e retorna o resultado. A pesquisa ocorrerá da seguinte forma.

 Class D -> Class B -> Class C -> Class A 

Se a classe B não tiver um método, ela invocará o método da classe C.

Aqui, sugerimos que você remova o método da classe B e verifique o que acontece. Fazendo isso, você terá uma ideia de como funciona a resolução do método.

Ordem de estilo antigo e novo

Na versão mais antiga do Python (2.1), estamos restritos a usar as classes antigas, mas Pitão (2.2 e continuação), podemos usar as novas classes. Por padrão, Python 3 possui classes originais (novas). O primeiro pai da nova classe de estilo herda da classe 'objeto' raiz do Python. Vejamos o seguinte exemplo -

grátis vs grátis

Exemplo -

 # Old style class class OldStyleClass: pass # New style class class NewStyleClass(object): pass 

O estilo de declaração de ambas as classes é diferente. Na resolução do método, as classes de estilo antigo seguem o algoritmo de profundidade da esquerda para a direita (DLR), enquanto as classes de estilo novo usam o algoritmo de linearização C3 enquanto executam herança múltipla.

Algoritmo DLR

Python cria uma lista de classes enquanto implementa a herança múltipla entre as classes. Essa lista é usada para determinar qual método deve ser chamado e se ele é invocado pelas instâncias.

Podemos assumir que trabalhar com seu nome, pois a resolução do método pesquisará primeiro em profundidade e depois irá da esquerda para a direita. Abaixo está o exemplo.

Exemplo -

 class A: pass class B: pass class C(A, B): pass class D(B, A): pass class E(C,D): pass 

Primeiro, o algoritmo procurará na classe de instância o método invocado. Se não for encontrado, vai para os primeiros pais, se também não for encontrado. Ele examinará o pai do pai. Isso continuará até o final da herança das classes.

No exemplo acima, a ordem de resolução do método será -

 class D -> class B -> class A -> class C -> class A 

Mas, A não pode estar presente duas vezes, então -

 class D -> class B -> class A -> class C -> 

Este algoritmo mostra o comportamento estranho da época. Vejamos o exemplo abaixo.

Exemplo -

 class A: pass class B: pass class C(A, B): pass class D(B, A): pass class E(C,D): pass 

De acordo com o Algoritmo DLR, a ordem será E, C, D, B, A. Existe a troca das classes A e B na classe C, o que é muito ambíguo. Isso significa que o algoritmo não preserva a propriedade de monotonicidade.

Samuele Perdoni foi a primeira pessoa a descobrir uma inconsistência entre os algoritmos MRO.

Algoritmo de Linearização C3

O Algoritmo de Linearização C3 é uma versão melhor do algoritmo DLR porque remove a inconsistência. Este algoritmo possui algumas restrições que são fornecidas a seguir.

exemplo de lista em java
  • Os filhos devem preceder os pais.
  • Se uma classe específica herda de uma ou mais classes, elas são salvas na ordem especificada na tupla da classe base.

Regras do Algoritmo de Linearização C3

  • A estrutura da ordem de resolução do método é definida pelo gráfico de herança.
  • O usuário deve visitar a superclasse somente após os métodos das classes locais serem visitados.
  • Preservar a monotonicidade

Método para classe de resolução de método

Python fornece duas maneiras de obter a ordem de resolução do método de uma classe - __mro__ atributo ou mro() método. Com a ajuda desses métodos, podemos exibir a ordem do método em que eles são resolvidos.

Vamos entender o exemplo a seguir.

Exemplo -

 class A: def myname(self): print(' I am a class A') class B(A): def myname(self): print(' I am a class B') class C(A): def myname(self): print('I am a class C') # classes ordering class D(B, C): pass # it prints the lookup order print(D.__mro__) print(C.mro()) 

Saída:

 (, , , , ) [, , ] 

Como podemos ver na saída acima, obtemos a ordem de resolução do método. Desta forma, o algoritmo de linearização C3 funciona para herança múltipla.