Jawaban:
Ikuti...:
>>> class A(object): pass
...
>>> A.__mro__
(<class '__main__.A'>, <type 'object'>)
>>> class B(A): pass
...
>>> B.__mro__
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
>>> class C(A): pass
...
>>> C.__mro__
(<class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
>>>
Selama kita memiliki satu warisan, __mro__
hanyalah tuple dari: kelas, basisnya, basis basisnya, dan seterusnya hinggaobject
(hanya bekerja untuk kelas gaya baru tentu saja).
Sekarang, dengan beberapa warisan ...:
>>> class D(B, C): pass
...
>>> D.__mro__
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>)
... Anda juga mendapatkan jaminan bahwa, dalam __mro__
, tidak ada kelas yang diduplikasi, dan tidak ada kelas setelah leluhurnya, kecuali bahwa kelas yang pertama kali masuk pada tingkat pewarisan berganda yang sama (seperti B dan C dalam contoh ini) ada di __mro__
kiri ke kanan.
Setiap atribut yang Anda dapatkan pada instance kelas, bukan hanya metode, secara konseptual melihat ke atas __mro__
, jadi, jika lebih dari satu kelas di antara leluhur menentukan nama itu, ini memberi tahu Anda di mana atribut akan ditemukan - di kelas pertama di yang __mro__
yang mendefinisikan nama itu.
mro
dapat dikustomisasi oleh metaclass, dipanggil sekali pada inisialisasi kelas, dan hasilnya disimpan dalam __mro__
- lihat docs.python.org/library/… .
mro()
singkatan dari Method Resolution Order. Ini mengembalikan daftar jenis kelas berasal, dalam urutan mereka mencari metode.
mro () atau __mro__ hanya berfungsi pada kelas gaya baru. Di python 3, mereka bekerja tanpa masalah. Tetapi dalam python 2 kelas-kelas tersebut perlu diwarisi dari object
.
Ini mungkin akan menunjukkan urutan resolusi.
class A(object):
def dothis(self):
print('I am from A class')
class B(A):
pass
class C(object):
def dothis(self):
print('I am from C class')
class D(B, C):
pass
d_instance= D()
d_instance.dothis()
print(D.mro())
dan tanggapan akan
I am from A class
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.C'>, <class 'object'>]
Aturannya adalah kedalaman-pertama, yang dalam hal ini berarti D, B, A, C.
Python biasanya menggunakan urutan kedalaman-pertama saat mencari kelas yang diwariskan, tetapi ketika dua kelas mewarisi dari kelas yang sama, Python menghapus penyebutan pertama dari kelas itu dari mro.
Urutan resolusi akan berbeda dalam warisan berlian.
class A(object):
def dothis(self):
print('I am from A class')
class B1(A):
def dothis(self):
print('I am from B1 class')
# pass
class B2(object):
def dothis(self):
print('I am from B2 class')
# pass
class B3(A):
def dothis(self):
print('I am from B3 class')
# Diamond inheritance
class D1(B1, B3):
pass
class D2(B1, B2):
pass
d1_instance = D1()
d1_instance.dothis()
# I am from B1 class
print(D1.__mro__)
# (<class '__main__.D1'>, <class '__main__.B1'>, <class '__main__.B3'>, <class '__main__.A'>, <class 'object'>)
d2_instance = D2()
d2_instance.dothis()
# I am from B1 class
print(D2.__mro__)
# (<class '__main__.D2'>, <class '__main__.B1'>, <class '__main__.A'>, <class '__main__.B2'>, <class 'object'>)
class B3
tetapi dalam kasus kedua itu pergi class A
setelahclass B1