logo

Ordinea de rezoluție a metodei în Python

În acest tutorial, vom afla despre ordinea de rezoluție a metodei, cunoscută și sub numele de MRO. Este un concept esențial al moștenirii Python.

Ordinea de rezoluție a metodei descrie calea de căutare a clasei care Piton folosește pentru a obține metoda corespunzătoare în clasele care conțin moștenirea multiplă.

Introducere

După cum știm că, o clasă care este moștenită se numește subclasă sau clasă părinte, în timp ce clasa care moștenește este cunoscută ca clasă sau subclasă copil. În moștenirea multiplă, o clasă poate consta din mai multe funcții, astfel încât tehnica ordinului de rezoluție a metodei este utilizată pentru a căuta ordinea în care este executată clasa de bază.

Cu cuvinte simple - „Metoda sau atributele sunt explorate în clasa curentă, dacă metoda nu este prezentă în clasa curentă, căutarea se mută la clasele părinte și așa mai departe”. Acesta este un exemplu de căutare în profunzime.

Joacă un rol esențial în moștenirea multiplă, unde aceeași metodă poate fi găsită în superclasele multiple.

Pentru a-l înțelege mai bine, să vedem cum îl putem folosi.

Exemplu -

 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()) 

Ieșire:

 I am a class C 

Explicație -

Există o moștenire multiplă în codul de mai sus. Am definit trei clase numite A, B și C, iar aceste clase au aceeași metodă numită numele meu(). Am creat o clasă de obiecte C. Obiectul a invocat clasa C, nu clasa, în timp ce clasa C a moștenit metoda clasei A.

Ordinea este urmată în codul de mai sus este clasa B -> clasa A. Această tehnică este cunoscută sub denumirea de MRO (method resolution order).

Să înțelegem un alt exemplu de moștenire multiplă.

Exemplu -

 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() 

Ieșire:

 I am a class B 

Explicație -

În codul de mai sus, am creat o altă clasă D fără a defini atributele de clasă care au moștenit clasa B și C. Când am invocat metoda numele meu(), merge la clasa D și caută numele meu( ) funcție. Dar clasa D nu are nicio declarație. Prin urmare, căutarea se transferă la clasa B, obține numele meu() funcția și returnează rezultatul. Căutarea va avea loc după cum urmează.

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

Dacă clasa B nu ar avea o metodă, va invoca metoda clasei C.

Aici, vă sugerăm să eliminați metoda clasei B și să verificați ce se întâmplă. Făcând acest lucru, vă veți face o idee despre cum funcționează rezoluția metodei.

Comanda stilului vechi și nou

În versiunea mai veche de Python (2.1), suntem restricționați să folosim vechile clase dar Piton (2.2 și continuare), putem folosi noile clase. În mod implicit, Python 3 are clase originale (noi). Primul părinte al noii clase de stil moștenește din clasa „obiect” rădăcină Python. Să vedem următorul exemplu -

Exemplu -

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

Stilul de declarare al ambelor clase este diferit. În rezoluția metodei, clasele de stil vechi urmează algoritmul de depth-first la stânga la dreapta (DLR), în timp ce noile clase de stil utilizează algoritmul de liniarizare C3 în timp ce efectuează moștenire multiplă.

Algoritmul DLR

Python creează o listă de clase în timp ce implementează moștenirea multiplă între clase. Această listă este folosită pentru a determina ce metodă trebuie apelată, una este invocată de instanțe.

Putem presupune că lucrul după numele său, deoarece rezoluția metodei va căuta mai întâi în profunzime, apoi va merge de la stânga la dreapta. Mai jos este exemplul.

Exemplu -

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

În primul rând, algoritmul va căuta în clasa de instanță metoda invocată. Dacă nu se găsește, intră în primii părinți, dacă nu se găsește și. Se va uita la părintele părintelui. Acest lucru va continua până la sfârșitul claselor de moștenire.

În exemplul de mai sus, ordinea de rezoluție a metodei va fi -

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

Dar, A nu poate fi prezent de două ori, așa că -

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

Acest algoritm arată comportamentul ciudat la momentul respectiv. Să vedem exemplul de mai jos.

Exemplu -

an în trimestre
 class A: pass class B: pass class C(A, B): pass class D(B, A): pass class E(C,D): pass 

Conform algoritmului DLR, ordinea va fi E, C, D, B, A. Există schimbul de clase A și B în clasa C, care este foarte ambiguu. Înseamnă că algoritmul nu păstrează proprietatea de monotonitate.

Samuele Perdoni a fost prima persoană care a descoperit o inconsecvență între algoritmii MRO.

C3 Algoritm de liniarizare

Algoritmul de liniarizare C3 este o versiune mai bună a algoritmului DLR, deoarece înlătură inconsecvența. Acest algoritm are unele restricții care sunt prezentate mai jos.

  • Copiii trebuie să-și precedă părinții.
  • Dacă o anumită clasă moștenește din una sau mai multe clase, acestea sunt salvate în ordinea specificată în tuplul clasei de bază.

Regulile algoritmului de liniarizare C3

  • Structura ordinii de rezoluție a metodei este definită de graficul de moștenire.
  • Utilizatorul trebuie să viziteze super-clasa numai după ce au fost vizitate metodele claselor locale.
  • Păstrează monotonitatea

Metodă pentru clasa Metoda Rezoluție

Python oferă două moduri de a obține ordinea de rezoluție a metodei a unei clase - __mro__ atribut sau mro() metodă. Cu ajutorul acestor metode, putem afișa ordinea metodei în care sunt rezolvate.

Să înțelegem următorul exemplu.

Exemplu -

 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()) 

Ieșire:

 (, , , , ) [, , ] 

După cum putem vedea în rezultatul de mai sus, obținem ordinea ordinii de rezoluție a metodei. În acest fel, algoritmul de liniarizare C3 funcționează pentru moștenirea multiplă.