logo

Poradie rozlíšenia metódy v Pythone

V tomto návode sa dozvieme o poradí rozlíšenia metód, ktoré je známe aj ako MRO. Je to základný koncept dedičnosti Pythonu.

Poradie rozlíšenia metódy popisuje cestu vyhľadávania triedy, ktorá Python používa na získanie vhodnej metódy v triedach, ktoré obsahujú viacnásobnú dedičnosť.

Úvod

Ako vieme, trieda, ktorá sa zdedí, sa nazýva podtrieda alebo nadradená trieda, zatiaľ čo trieda, ktorá zdedí, je známa ako podtrieda alebo podtrieda. Pri viacnásobnom dedení môže trieda pozostávať z mnohých funkcií, takže technika poradia rozlíšenia metód sa používa na vyhľadávanie poradia, v ktorom sa vykonáva základná trieda.

Jednoducho povedané - 'Metóda alebo atribúty sa skúmajú v aktuálnej triede, ak metóda nie je prítomná v aktuálnej triede, vyhľadávanie sa presunie do rodičovských tried atď.'. Toto je príklad hĺbkového hľadania.

Hrá zásadnú úlohu pri viacnásobnom dedení, kde rovnakú metódu možno nájsť vo viacerých nadtriedach.

Aby sme to lepšie pochopili, pozrime sa, ako to môžeme použiť.

Príklad -

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

Výkon:

 I am a class C 

vysvetlenie -

Vo vyššie uvedenom kóde existuje viacnásobné dedičstvo. Definovali sme tri triedy s názvom A, B a C a tieto triedy majú rovnaký názov nazývaný metóda moje meno(). Vytvorili sme triedu objektov C. Objekt vyvolal triedu C, nie triedu, zatiaľ čo trieda C zdedila metódu triedy A.

Poradie je dodržané vo vyššie uvedenom kóde je trieda B -> trieda A. Táto technika je známa ako MRO (method resolution order).

Poďme pochopiť ďalší príklad viacnásobného dedenia.

Príklad -

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

Výkon:

 I am a class B 

vysvetlenie -

Vo vyššie uvedenom kóde sme vytvorili ďalšiu triedu D bez definovania atribútov triedy, ktorá zdedila triedu B a C. Keď sme vyvolali metódu moje meno(), prejde do triedy D a vyhľadá moje meno( ) funkciu. Ale trieda D nemá žiadne vyhlásenie. Preto sa vyhľadávanie presunie do triedy B, dostane moje meno() funkciu a vráti výsledok. Vyhľadávanie bude prebiehať nasledovne.

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

Ak by trieda B nemala metódu, vyvolá metódu triedy C.

Tu vám odporúčame odstrániť metódu triedy B a skontrolovať, čo sa stane. Týmto spôsobom získate predstavu o tom, ako funguje rozlíšenie metódy.

Poriadok starého a nového štýlu

V staršej verzii Pythonu (2.1) môžeme používať staré triedy, ale Python (2.2 a pokračovať), môžeme použiť nové triedy. Štandardne má Python 3 pôvodné (nové) triedy. Prvý rodič novej triedy štýlu dedí z koreňovej triedy 'objektu' Pythonu. Pozrime sa na nasledujúci príklad -

Príklad -

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

Deklaračný štýl oboch tried je odlišný. V rozlíšení metódy sa triedy starého štýlu riadia algoritmom z hĺbky prvej zľava doprava (DLR), zatiaľ čo nové triedy štýlu používajú algoritmus linearizácie C3 pri vykonávaní viacnásobného dedenia.

Algoritmus DLR

Python vytvára zoznam tried a zároveň implementuje viacnásobnú dedičnosť medzi triedami. Tento zoznam sa používa na určenie, ktorá metóda sa musí volať, ktorú inštancie vyvolávajú.

čo je $home linux

Môžeme predpokladať, že pracuje podľa názvu, pretože rozlíšenie metódy bude najprv hľadať hĺbku a potom pôjde zľava doprava. Nižšie je uvedený príklad.

Príklad -

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

Po prvé, algoritmus vyhľadá v triede inštancií vyvolanú metódu. Ak sa nenájde, ide do prvého rodiča, ak sa nenájde ani tam. Pozrie sa na rodiča rodiča. Toto bude pokračovať až do konca dedenia tried.

Vo vyššie uvedenom príklade bude poradie rozlíšenia metódy -

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

Ale A nemôže byť dvakrát prítomné, takže -

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

Tento algoritmus ukazuje zvláštne správanie v tom čase. Pozrime sa na príklad nižšie.

Príklad -

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

Podľa algoritmu DLR bude poradie E, C, D, B, A. V triede C dochádza k zámene tried A a B, čo je veľmi nejednoznačné. To znamená, že algoritmus nezachováva vlastnosť monotónnosti.

Samuele Perdoni bol prvým človekom, ktorý objavil nezrovnalosť medzi algoritmami MRO.

Linearizačný algoritmus C3

Linearizačný algoritmus C3 je lepšou verziou algoritmu DLR, pretože odstraňuje nekonzistentnosť. Tento algoritmus má určité obmedzenia, ktoré sú uvedené nižšie.

  • Deti musia predbiehať svojich rodičov.
  • Ak konkrétna trieda dedí z jednej alebo viacerých tried, uložia sa v poradí špecifikovanom v n-tici základnej triedy.

Pravidlá lineárneho algoritmu C3

  • Štruktúra poradia rozlíšenia metódy je definovaná grafom dedičnosti.
  • Používateľ musí navštíviť super triedu až po návšteve metód miestnych tried.
  • Zachovať monotónnosť

Metóda pre triedu Method Resolution

Python poskytuje dva spôsoby, ako získať poradie rozlíšenia metód triedy - __mro__ atribút resp mro() metóda. Pomocou týchto metód môžeme zobraziť poradie metódy, v ktorej sú vyriešené.

Poďme pochopiť nasledujúci príklad.

Príklad -

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

Výkon:

 (, , , , ) [, , ] 

Ako môžeme vidieť vo vyššie uvedenom výstupe, dostaneme poradie poradia rozlíšenia metódy. Takýmto spôsobom pracuje linearizačný algoritmus C3 pre viacnásobnú dedičnosť.