Šajā apmācībā mēs uzzināsim par metodes izšķiršanas secību, kas ir pazīstama arī kā MRO. Tas ir būtisks Python mantojuma jēdziens.
Metodes izšķirtspējas secība apraksta meklēšanas ceļu klasē, kas Python izmanto, lai iegūtu atbilstošo metodi klasēs, kas satur vairāku mantojumu.
Ievads
Kā mēs zinām, klasi, kas tiek mantota, sauc par apakšklasi vai vecāku klasi, savukārt klasi, kas manto, sauc par pakārtoto klasi vai apakšklasi. Vairāku mantojuma gadījumā klase var sastāvēt no daudzām funkcijām, tāpēc metodes izšķirtspējas secības paņēmiens tiek izmantots, lai meklētu secību, kādā tiek izpildīta bāzes klase.
Vienkāršiem vārdiem sakot - 'Metode vai atribūti tiek izpētīti pašreizējā klasē, ja metodes nav pašreizējā klasē, meklēšana tiek pārvietota uz vecākklasēm utt. Šis ir dziļuma meklēšanas piemērs.
Tai ir būtiska loma daudzkārtējā mantojumā, kur vienu un to pašu metodi var atrast vairākās virsklasēs.
Lai to labāk izprastu, redzēsim, kā mēs varam to izmantot.
Piemērs -
java konvenciju nosaukumu piešķiršana
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())
Izvade:
I am a class C
Paskaidrojums -
Iepriekš minētajā kodā ir daudzkārtējs mantojums. Mēs esam definējuši trīs klases, ko sauc par A, B un C, un šīm klasēm ir tāda paša nosaukuma metode Mans vārds(). Mēs izveidojām objekta klasi C. Objekts izsauca C klasi, nevis klasi, savukārt C klase mantoja A klases metodi.
kat timpf augums
Kārtība tiek ievērota iepriekš minētajā kodā B klase -> A klase. Šī metode ir pazīstama kā MRO (metodes izšķiršanas secība).
Sapratīsim vēl vienu vairākkārtējas mantojuma piemēru.
Piemērs -
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()
Izvade:
I am a class B
Paskaidrojums -
Iepriekš minētajā kodā mēs esam izveidojuši citu D klasi, nedefinējot klases atribūtus, kas mantojuši B un C klasi. Kad mēs izmantojām metodi Mans vārds(), tas dodas uz D klasi un meklē Mans vārds( ) funkcija. Bet D klasei nav nekādas deklarācijas. Tādējādi meklēšana pāriet uz B klasi, iegūst Mans vārds() funkciju un atgriež rezultātu. Meklēšana notiks šādi.
Class D -> Class B -> Class C -> Class A
Ja B klasei nebūtu metodes, tā izsauks C klases metodi.
Šeit mēs iesakām noņemt B klases metodi un pārbaudīt, kas notiek. To darot, jūs iegūsit priekšstatu par metodes izšķirtspējas darbību.
Vecā un jaunā stila pasūtījums
Vecākajā Python versijā (2.1) mēs drīkstam izmantot tikai vecās klases, bet Python (2.2 un turpināt), mēs varam izmantot jaunās klases. Pēc noklusējuma Python 3 ir oriģinālās (jaunas) klases. Jaunās stila klases pirmais vecāks ir mantojis no Python saknes 'objektu' klases. Apskatīsim šādu piemēru -
Piemērs -
# Old style class class OldStyleClass: pass # New style class class NewStyleClass(object): pass
Abu klašu deklarācijas stils ir atšķirīgs. Metodes izšķirtspējā vecā stila klases ievēro algoritmu “dziļums pirmais no kreisās uz labo pusi” (DLR), savukārt jaunās stila klases izmanto C3 linearizācijas algoritmu, vienlaikus veicot vairākas mantošanas.
DLR algoritms
Python izveido klašu sarakstu, vienlaikus ieviešot daudzkārtējo mantojumu starp klasēm. Šis saraksts tiek izmantots, lai noteiktu, kura metode ir jāizsauc, kuru gadījumi izsauc.
Mēs varam pieņemt, ka strādāsim pēc tā nosaukuma, jo metodes izšķirtspēja vispirms meklēs dziļumā un pēc tam virzīsies no kreisās uz labo pusi. Zemāk ir piemērs.
Piemērs -
class A: pass class B: pass class C(A, B): pass class D(B, A): pass class E(C,D): pass
Pirmkārt, algoritms instanču klasē meklēs izsaukto metodi. Ja nav atrasts, tas nonāk pirmajos vecākos, ja arī nav atrasts. Tas izskatīs vecāku vecākus. Tas turpināsies līdz mantošanas klašu beigām.
java slēdža futrālis
Iepriekš minētajā piemērā metodes izšķirtspējas secība būs:
class D -> class B -> class A -> class C -> class A
Bet A nevar būt divreiz klāt, tāpēc -
class D -> class B -> class A -> class C ->
Šis algoritms parāda dīvaino uzvedību tajā laikā. Apskatīsim zemāk redzamo piemēru.
Piemērs -
class A: pass class B: pass class C(A, B): pass class D(B, A): pass class E(C,D): pass
Saskaņā ar DLR algoritmu secība būs E, C, D, B, A. C klasē notiek A un B klašu apmaiņa, kas ir ļoti neskaidra. Tas nozīmē, ka algoritms nesaglabā monotonitātes īpašību.
Samuele Perdoni bija pirmā persona, kas atklāja neatbilstību starp MRO algoritmiem.
kā java savienot virknes
C3 Linearizācijas algoritms
C3 linearizācijas algoritms ir labāka DLR algoritma versija, jo tas novērš neatbilstību. Šim algoritmam ir daži ierobežojumi, kas ir norādīti tālāk.
- Bērniem ir jābūt priekšā saviem vecākiem.
- Ja konkrēta klase manto no vienas vai vairākām klasēm, tās tiek saglabātas tādā secībā, kas norādīta bāzes klases kortežā.
C3 linearizācijas algoritma noteikumi
- Metodes izšķirtspējas secības struktūru nosaka mantojuma grafiks.
- Lietotājam ir jāapmeklē superklase tikai pēc vietējo nodarbību metožu apmeklēšanas.
- Saglabājiet monotonitāti
Metode izšķirtspējas klasei
Python nodrošina divus veidus, kā iegūt klases metodes izšķirtspējas secību - __mro__ atribūts vai mro () metodi. Ar šo metožu palīdzību mēs varam parādīt metodes secību, kādā tās tiek atrisinātas.
Sapratīsim šādu piemēru.
Piemērs -
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())
Izvade:
(, , , , ) [, , ]
Kā redzams iepriekš minētajā izvadē, mēs iegūstam metodes izšķirtspējas secību. Tādā veidā C3 linearizācijas algoritms darbojas vairākkārtējai mantošanai.