Skip to main content

Method Resolution Order

MRO (Method Resolution Order) adalah aturan yang digunakan Python untuk menentukan urutan pencarian attribute dan method pada sebuah class atau object.

MRO menjadi sangat penting ketika kita menggunakan multiple inheritance, karena sebuah class dapat memiliki lebih dari satu parent class.

Dengan MRO, Python memiliki aturan yang jelas untuk menentukan class mana yang harus diperiksa terlebih dahulu ketika mencari attribute atau method.


Mengapa MRO Dibutuhkan?​

Pada inheritance sederhana, struktur class biasanya mudah dipahami:

A
│
└── B

Ketika Python mencari attribute atau method pada object B, Python dapat mencari dari:

B → A → object

Namun, pada multiple inheritance, strukturnya dapat menjadi lebih kompleks:

A
/ \
B C
\ /
D

Class D memiliki dua parent:

class D(B, C):
pass

Jika B dan C memiliki method atau attribute dengan nama yang sama, Python harus menentukan mana yang digunakan terlebih dahulu.

MRO menentukan urutan tersebut.


Contoh Hirarki MRO​

Perhatikan contoh berikut:

class A:
num = 10


class B(A):
pass


class C(A):
num = 1


class D(B, C):
pass

Struktur inheritance tersebut adalah:

A
/ \
B C
\ /
D

Class D mewarisi dari:

B
C

Sedangkan B dan C sama-sama mewarisi A.


Apa yang Terjadi Ketika Memanggil D.num?​

Sekarang kita menjalankan:

print(D.num)

Python harus mencari attribute num.

MRO menentukan urutan pencarian:

D
↓
B
↓
C
↓
A
↓
object

Python pertama-tama memeriksa D.

D tidak memiliki num.

Kemudian Python memeriksa B.

B juga tidak memiliki num.

Selanjutnya Python memeriksa C.

C memiliki:

num = 1

Maka pencarian berhenti.

Hasilnya:

1

Mengapa Bukan 10?​

Class A memiliki:

num = 10

Sedangkan class C memiliki:

num = 1

Meskipun A juga memiliki num, Python menemukan num milik C terlebih dahulu berdasarkan MRO.

Urutannya:

D → B → C → A → object

Karena C diperiksa sebelum A, maka:

D.num

menghasilkan:

1

Melihat MRO dengan .mro()​

Python menyediakan method mro() untuk melihat urutan MRO sebuah class.

Contoh:

print(D.mro())

Hasilnya:

[
<class '__main__.D'>,
<class '__main__.B'>,
<class '__main__.C'>,
<class '__main__.A'>,
<class 'object'>
]

Jika disederhanakan:

D
↓
B
↓
C
↓
A
↓
object

Urutan tersebut menunjukkan bagaimana Python mencari attribute dan method.


Melihat MRO dengan __mro__​

Selain menggunakan:

D.mro()

kita juga dapat menggunakan attribute:

D.__mro__

Contoh:

print(D.__mro__)

Hasilnya akan menunjukkan urutan class yang sama.

Kedua pendekatan tersebut dapat digunakan untuk melihat MRO:

D.mro()

dan:

D.__mro__

MRO dan Pencarian Method​

MRO tidak hanya digunakan untuk mencari attribute.

MRO juga digunakan ketika Python mencari method.

Misalnya:

class A:

def hello(self):
print("A")


class B(A):

def hello(self):
print("B")


class C(A):

def hello(self):
print("C")


class D(B, C):
pass

Kemudian:

d = D()

d.hello()

Python akan mengikuti MRO.

Urutannya:

D → B → C → A → object

Karena B memiliki method hello(), Python akan menggunakan method tersebut.

Output:

B

Urutan Pewarisan Berpengaruh pada MRO​

Perhatikan:

class D(B, C):
pass

Urutan parent ditulis:

B → C

Jika kita mengubahnya menjadi:

class D(C, B):
pass

urutan MRO juga dapat berubah.

Secara konsep:

D → C → B → A → object

Oleh karena itu, urutan parent class dalam multiple inheritance sangat penting.


C3 Linearization​

Python menggunakan algoritma C3 Linearization untuk menentukan MRO.

C3 Linearization memastikan bahwa urutan inheritance tetap konsisten dan memenuhi aturan tertentu.

Salah satu tujuan pentingnya adalah menjaga:

  • Child class diperiksa sebelum parent class.
  • Urutan parent class tetap dihormati.
  • Hubungan inheritance tetap konsisten.
  • Ambiguitas dalam multiple inheritance dapat dihindari.

Untuk tahap awal pembelajaran, kita tidak perlu menghitung algoritma C3 Linearization secara manual.

Yang penting dipahami adalah bahwa Python menggunakan mekanisme tersebut untuk menentukan MRO.


MRO dan Diamond Problem​

MRO sangat berkaitan dengan Diamond Problem.

Contoh struktur diamond:

A
/ \
B C
\ /
D

Dalam struktur tersebut:

  • B mewarisi A.
  • C mewarisi A.
  • D mewarisi B dan C.

Masalahnya adalah ketika beberapa class memiliki method atau attribute dengan nama yang sama.

Misalnya:

class A:

def hello(self):
print("A")


class B(A):

def hello(self):
print("B")


class C(A):

def hello(self):
print("C")


class D(B, C):
pass

Ketika:

d = D()

d.hello()

Python harus menentukan apakah menggunakan:

B.hello()

atau:

C.hello()

MRO memberikan aturan yang konsisten untuk menentukan jawabannya.


MRO pada Contoh Diamond​

Untuk:

class D(B, C):
pass

MRO-nya adalah:

D
↓
B
↓
C
↓
A
↓
object

Karena B berada sebelum C, maka method hello() milik B akan ditemukan terlebih dahulu.

Output:

B

MRO dan Base Class object​

Seperti yang telah dipelajari sebelumnya, semua class Python pada akhirnya memiliki hubungan dengan base class:

object

Karena itu, MRO biasanya berakhir pada:

object

Contohnya:

D
↓
B
↓
C
↓
A
↓
object

Jika attribute atau method tidak ditemukan pada seluruh class sebelumnya, Python akan terus mencari hingga object.


MRO dalam Multiple Inheritance​

Pada multiple inheritance:

class HybridBorg(Wizard, Archer):
pass

Python harus menentukan urutan pencarian.

Kita dapat melihatnya dengan:

print(HybridBorg.mro())

atau:

print(HybridBorg.__mro__)

Hal ini sangat berguna ketika kita ingin mengetahui dari mana sebuah method atau attribute berasal.


Mengapa MRO Penting?​

MRO penting karena memungkinkan Python menentukan perilaku object secara konsisten.

Tanpa MRO, multiple inheritance dapat menghasilkan kebingungan ketika beberapa parent class memiliki method atau attribute yang sama.

Dengan MRO, Python memiliki aturan yang jelas untuk menentukan:

Class mana yang diperiksa terlebih dahulu?

Kemudian:

Jika tidak ditemukan, class mana yang diperiksa berikutnya?

Cara Praktis Memeriksa MRO​

Ketika menggunakan multiple inheritance dan mengalami perilaku yang tidak sesuai harapan, kita dapat memeriksa MRO menggunakan:

ClassName.mro()

Contohnya:

print(D.mro())

atau:

print(D.__mro__)

Dengan melihat hasil tersebut, kita dapat mengetahui urutan pencarian Python.


Kesimpulan​

MRO (Method Resolution Order) adalah aturan yang menentukan urutan Python dalam mencari attribute dan method pada inheritance hierarchy.

MRO sangat penting pada multiple inheritance.

Contoh:

class D(B, C):
pass

Python dapat memiliki MRO:

D → B → C → A → object

Kita dapat melihat MRO menggunakan:

D.mro()

atau:

D.__mro__

Python menggunakan C3 Linearization untuk menentukan MRO.

MRO juga membantu mengatasi ambiguitas pada Diamond Problem sehingga pencarian method dan attribute tetap memiliki urutan yang konsisten.

Setelah memahami MRO, konsep berikutnya yang penting untuk dipelajari adalah bagaimana super() bekerja berdasarkan Method Resolution Order, terutama pada multiple inheritance.