logo

Metodupplösningsordning i Python

I den här handledningen kommer vi att lära oss om metodupplösningsordning, som också är känd som MRO. Det är ett viktigt koncept för Python-arv.

Metodupplösningsordning beskriver sökvägen för klassen som Pytonorm använder för att få rätt metod i klasser som innehåller multi-arv.

Introduktion

Som vi vet det kallas en klass som ärvs för underklassen eller förälderklassen, medan klassen som ärver är känd som en underklass eller underklass. I multi-arv kan en klass bestå av många funktioner, så metodupplösningsordningstekniken används för att söka i den ordning i vilken basklassen exekveras.

Med enkla ord - 'Metoden eller attributen utforskas i den aktuella klassen, om metoden inte finns i den aktuella klassen, flyttar sökningen till de överordnade klasserna, och så vidare'. Detta är ett exempel på en djup-först-sökning.

Det spelar en viktig roll i multipelt arv där samma metod kan hittas i de multipla superklasserna.

För att förstå det på ett bättre sätt, låt oss se hur vi kan använda det.

Exempel -

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

Produktion:

 I am a class C 

Förklaring -

Det finns ett multipelt arv i ovanstående kod. Vi har definierat tre klasser som kallas A, B och C, och dessa klasser har samma namnmetod som kallas mitt namn(). Vi skapade en objektklass C. Objektet anropade klass C, inte klassen, medan klass C ärvde klass A-metoden.

Ordningen följs i ovanstående kod är klass B - > klass A. Denna teknik är känd som MRO (metodupplösningsordning).

javascript sömn

Låt oss förstå ett annat exempel på multipelt arv.

Exempel -

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

Produktion:

 I am a class B 

Förklaring -

I ovanstående kod har vi skapat ytterligare en D-klass utan att definiera klassattribut som ärvde B- och C-klass. När vi åberopade metoden mitt namn(), den går till klass D och söker efter mitt namn( ) funktion. Men klass D har ingen deklaration. Därför överförs sökningen till klass B, får mitt namn() funktion och returnerar resultatet. Sökningen kommer att ske enligt följande.

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

Om klass B inte skulle ha en metod, kommer den att anropa klass C-metoden.

Här föreslår vi att du tar bort klass B-metoden och kontrollerar vad som händer. Genom att göra detta får du en uppfattning om hur metodupplösningen fungerar.

Gammal och ny stilordning

I den äldre versionen av Python (2.1) är vi begränsade till att använda de gamla klasserna men Pytonorm (2.2 & fortsätt), kan vi använda de nya klasserna. Som standard har Python 3 ursprungliga (nya) klasser. Den nya stilklassens första förälder ärver från Python-roten 'objekt'-klassen. Låt oss se följande exempel -

Exempel -

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

Deklarationsstilen för båda klasserna är olika. I metodupplösningen följer klasser av gammal stil algoritmen djup-först från vänster till höger (DLR), medan nya stilklasser använder C3-lineariseringsalgoritmen medan de utför multipel nedärvning.

DLR-algoritm

Python skapar en lista med klasser samtidigt som det multipla arvet mellan klasserna implementeras. Den listan används för att bestämma vilken metod som måste kallas en anropas av instanser.

Vi kan anta att man arbetar efter dess namn eftersom metodupplösningen kommer att söka djupet först och sedan gå från vänster till höger. Nedan är exemplet.

konvertera en sträng till heltal

Exempel -

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

Först kommer algoritmen att söka i instansklassen efter den anropade metoden. Om det inte hittas, går det in i de första föräldrarna, om det inte heller finns. Det kommer att titta på föräldern till föräldern. Detta kommer att fortsätta till slutet av ärvningsklasserna.

I exemplet ovan kommer metodupplösningsordningen att vara -

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

Men A kan inte vara närvarande två gånger så -

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

Denna algoritm visar det konstiga beteendet vid den tiden. Låt oss se exemplet nedan.

Exempel -

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

Enligt DLR Algorithm kommer ordningen att vara E, C, D, B, A. Det finns ett utbyte av klasserna A & B i klass C, vilket är mycket tvetydigt. Det betyder att algoritmen inte bevarar monotoniegenskapen.

Samuele Perdoni var den första personen som upptäckte en inkonsekvens mellan MRO-algoritmerna.

C3 linjäriseringsalgoritm

C3 Linearization Algorithm är en bättre version av DLR-algoritmen eftersom den tar bort inkonsekvensen. Denna algoritm har några begränsningar som anges nedan.

  • Barn måste gå före sina föräldrar.
  • Om en viss klass ärver från en eller flera klasser, sparas de i den ordning som anges i basklassens tuppel.

Regler för C3-lineariseringsalgoritm

  • Strukturen för metodupplösningsordningen definieras av arvsgrafen.
  • Användaren måste besöka superklassen först efter att metoderna för de lokala klasserna har besökts.
  • Bevara monotoniteten

Metod för metodupplösningsklass

Python tillhandahåller två sätt att få metodupplösningsordningen för en klass - __mro__ attribut eller mro() metod. Med hjälp av dessa metoder kan vi visa i vilken ordning de är lösta.

Låt oss förstå följande exempel.

Exempel -

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

Produktion:

 (, , , , ) [, , ] 

Som vi kan se i ovanstående utdata får vi ordningen för metodupplösningsordningen. På ett sådant sätt fungerar C3-lineariseringsalgoritmen för multipelt arv.