U ovom vodiču naučit ćemo o redoslijedu rješavanja metoda, koji je također poznat kao MRO. To je bitan koncept Python nasljeđivanja.
char + int u Javi
Redoslijed razlučivanja metode opisuje put pretraživanja klase koja Piton koristi za dobivanje odgovarajuće metode u klasama koje sadrže višestruko nasljeđivanje.
Uvod
Kao što znamo, klasa koja se nasljeđuje naziva se podklasa ili klasa roditelj, dok je klasa koja nasljeđuje poznata kao klasa dijete ili podklasa. U višestrukom nasljeđivanju, klasa se može sastojati od mnogo funkcija, tako da se tehnika redoslijeda razlučivanja metoda koristi za pretraživanje redoslijeda kojim se osnovna klasa izvodi.
Jednostavnim riječima - 'Metoda ili atributi se istražuju u trenutnoj klasi, ako metoda nije prisutna u trenutnoj klasi, pretraživanje se premješta na nadređene klase, i tako dalje'. Ovo je primjer pretraživanja najprije u dubinu.
Igra bitnu ulogu u višestrukom nasljeđivanju gdje se ista metoda može pronaći u višestrukim superklasama.
Da bismo ga bolje razumjeli, pogledajmo kako ga možemo koristiti.
Primjer -
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())
Izlaz:
I am a class C
Objašnjenje -
U gornjem kodu postoji višestruko nasljeđivanje. Definirali smo tri klase nazvane A, B i C, a te klase imaju isto ime pod nazivom metoda moje ime(). Stvorili smo klasu objekta C. Objekt je pozvao klasu C, a ne klasu, dok je klasa C naslijedila metodu klase A.
Redoslijed je u gornjem kodu klasa B - > klasa A. Ova tehnika je poznata kao MRO (method resolution order).
Razumimo još jedan primjer višestrukog nasljeđivanja.
Primjer -
bash za petlju 1 do 10
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()
Izlaz:
I am a class B
Objašnjenje -
U gornjem kodu stvorili smo drugu D klasu bez definiranja atributa klase koji su naslijedili B i C klasu. Kada smo pozvali metodu moje ime(), ide u klasu D i traži moje ime( ) funkcija. Ali klasa D nema nikakvu deklaraciju. Dakle, pretraživanje se prenosi u klasu B, dobiva moje ime() funkciju i vraća rezultat. Pretraga će se odvijati na sljedeći način.
Class D -> Class B -> Class C -> Class A
Ako klasa B nema metodu, pozvat će metodu klase C.
Ovdje predlažemo da uklonite metodu klase B i provjerite što se događa. Čineći to, dobit ćete predodžbu o tome kako funkcionira rezolucija metode.
Redoslijed starog i novog stila
U starijoj verziji Pythona (2.1), ograničeni smo na korištenje starih klasa, ali Piton (2.2 & nastaviti), možemo koristiti nove klase. Prema zadanim postavkama, Python 3 ima originalne (nove) klase. Prvi roditelj nove klase stila nasljeđuje od Python korijenske klase 'objekt'. Pogledajmo sljedeći primjer -
Primjer -
# Old style class class OldStyleClass: pass # New style class class NewStyleClass(object): pass
Stil deklaracije obje klase je različit. U rezoluciji metode, klase starog stila slijede dubinski algoritam slijeva na desno (DLR), dok nove klase stila koriste algoritam C3 linearizacije dok izvode višestruko nasljeđivanje.
DLR algoritam
Python stvara popis klasa dok implementira višestruko nasljeđivanje između klasa. Taj se popis koristi za određivanje koja se metoda mora pozvati koju instance pozivaju.
Možemo pretpostaviti da radimo po njegovom imenu jer će rezolucija metode pretraživati prvo u dubinu, a zatim ići slijeva nadesno. Ispod je primjer.
Primjer -
class A: pass class B: pass class C(A, B): pass class D(B, A): pass class E(C,D): pass
Prvo, algoritam će tražiti pozvanu metodu u klasi instance. Ako se ne pronađe, ide u prve roditelje, ako se također ne pronađe. Tražit će roditelja roditelja. To će se nastaviti do kraja klasa nasljeđivanja.
arraylist u Javi
U gornjem primjeru, redoslijed rješavanja metoda bit će -
class D -> class B -> class A -> class C -> class A
Ali, A ne može biti dva puta prisutno pa -
class D -> class B -> class A -> class C ->
Ovaj algoritam pokazuje čudno ponašanje u to vrijeme. Pogledajmo donji primjer.
df loc
Primjer -
class A: pass class B: pass class C(A, B): pass class D(B, A): pass class E(C,D): pass
Prema DLR algoritmu, poredak će biti E, C, D, B, A. Postoji zamjena klasa A i B u klasi C, što je vrlo dvosmisleno. To znači da algoritam ne čuva svojstvo monotonosti.
Samuele Perdoni bio je prva osoba koja je otkrila nedosljednost između MRO algoritama.
C3 algoritam linearizacije
C3 algoritam linearizacije je bolja verzija DLR algoritma jer uklanja nedosljednost. Ovaj algoritam ima neka ograničenja koja su navedena u nastavku.
- Djeca moraju biti ispred svojih roditelja.
- Ako određena klasa nasljeđuje jednu ili više klasa, one se spremaju redoslijedom navedenim u torki osnovne klase.
Pravila algoritma C3 linearizacije
- Struktura redoslijeda razlučivanja metode definirana je grafom nasljeđivanja.
- Korisnik mora posjetiti super klasu tek nakon što su posjećene metode lokalnih klasa.
- Sačuvajte monotonost
Metoda za klasu Razlučivost metode
Python nudi dva načina za dobivanje redoslijeda razlučivanja metode klase - __mro__ atribut ili mro() metoda. Uz pomoć ovih metoda možemo prikazati redoslijed metoda u kojem su riješene.
Razumimo sljedeći primjer.
Primjer -
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())
Izlaz:
(, , , , ) [, , ]
Kao što možemo vidjeti u gornjem izlazu, dobivamo redoslijed redoslijeda rezolucije metode. Na taj način C3 linearizacijski algoritam radi za višestruko nasljeđivanje.