logo

Ред за разрешаване на метод в Python

В този урок ще научим за реда на разрешаване на метода, който е известен също като MRO. Това е основна концепция за наследяването на Python.

Редът за разрешаване на метода описва пътя за търсене на класа, който Python използва за получаване на подходящия метод в класове, които съдържат мулти-наследяване.

Въведение

Както знаем, класът, който се наследява, се нарича подклас или родителски клас, докато класът, който наследява, е известен като дъщерен клас или подклас. При мулти-наследяването един клас може да се състои от много функции, така че техниката на реда за разрешаване на метода се използва за търсене на реда, в който се изпълнява базовият клас.

... в java

С прости думи - „Методът или атрибутите се изследват в текущия клас, ако методът не присъства в текущия клас, търсенето се премества в родителските класове и т.н.“. Това е пример за търсене в дълбочина.

Той играе съществена роля при множественото наследяване, където един и същ метод може да бъде намерен в множество суперкласове.

За да го разберем по-добре, нека видим как можем да го използваме.

пример -

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

Изход:

 I am a class C 

Обяснение -

В горния код има множествено наследяване. Дефинирахме три класа, наречени A, B и C, и тези класове имат едно и също име, наречен метод моето име(). Създадохме обект клас C. Обектът извика клас C, а не класа, докато клас C наследи метода клас A.

Редът е следван в горния код клас B -> клас A. Тази техника е известна като MRO (метод резолюция ред).

Нека разберем друг пример за множествено наследяване.

пример -

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

Изход:

 I am a class B 

Обяснение -

В горния код създадохме друг D клас, без да дефинираме атрибути на класа, които са наследили B и C клас. Когато извикахме метода моето име(), отива в клас D и търси моето име( ) функция. Но клас D няма никаква декларация. Следователно търсенето се прехвърля в клас B, получава моето име() функция и връща резултата. Търсенето ще се проведе по следния начин.

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

Ако клас B няма метод, той ще извика метода от клас C.

Тук ви предлагаме да премахнете метода от клас B и да проверите какво се случва. Като направите това, вие ще получите представа как работи разделителната способност на метода.

Ред в стар и нов стил

В по-старата версия на Python (2.1) сме ограничени да използваме старите класове, но Python (2.2 & продължи), можем да използваме новите класове. По подразбиране Python 3 има оригинални (нови) класове. Първият родител на новия стилов клас наследява от основния клас „обект“ на Python. Да видим следния пример -

пример -

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

Стилът на декларация на двата класа е различен. В разделителната способност на метода класовете от стар стил следват алгоритъма за дълбочина първо отляво надясно (DLR), докато новите класове от стил използват алгоритъма за линеаризация C3, докато извършват множествено наследяване.

java константа

DLR алгоритъм

Python създава списък от класове, докато прилага множественото наследяване между класовете. Този списък се използва, за да се определи кой метод трябва да бъде извикан, който се извиква от екземпляри.

Можем да предположим, че работим с неговото име, тъй като резолюцията на метода ще търси първо в дълбочина и след това ще премине отляво надясно. По-долу е примерът.

пример -

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

Първо, алгоритъмът ще търси в класа на екземпляра извикания метод. Ако не се намери, отива в първите родители, ако има също не се намери. Ще търси родителя на родителя. Това ще продължи до края на наследяващите класове.

В горния пример редът на разрешаване на метода ще бъде -

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

Но А не може да присъства два пъти, така че -

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

Този алгоритъм показва странното поведение по това време. Нека видим примера по-долу.

пример -

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

Според DLR алгоритъма редът ще бъде E, C, D, B, A. Има размяна на класове A и B в клас C, което е много двусмислено. Това означава, че алгоритъмът не запазва свойството монотонност.

Самуеле Пердони беше първият човек, който откри несъответствие между MRO алгоритмите.

C3 Алгоритъм за линеаризация

Алгоритъмът за линеаризация C3 е по-добра версия на алгоритъма DLR, тъй като премахва несъответствието. Този алгоритъм има някои ограничения, дадени по-долу.

  • Децата трябва да предхождат родителите си.
  • Ако определен клас наследява от един или повече класове, те се записват в реда, посочен в кортежа на базовия клас.

Правила на C3 алгоритъм за линеаризация

  • Структурата на реда за разрешаване на метода се определя от графа на наследяване.
  • Потребителят трябва да посети супер класа само след като са посетени методите на локалните класове.
  • Запазете монотонността

Метод за клас Резолюция на метода

Python предоставя два начина за получаване на реда за разрешаване на метода на клас - __mro__ атрибут или мро() метод. С помощта на тези методи можем да покажем реда на метода, в който са разрешени.

Нека разберем следния пример.

преобразуване на низ в цяло число в java

пример -

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

Изход:

 (, , , , ) [, , ] 

Както можем да видим в горния изход, получаваме реда на реда за разрешаване на метода. По този начин алгоритъмът за линеаризация C3 работи за множествено наследяване.