Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimanakah subkelas python menggunakan MRO dalam pelbagai warisan?

Bagaimanakah subkelas python menggunakan MRO dalam pelbagai warisan?

WBOY
WBOYke hadapan
2023-04-19 18:19:131534semak imbas

Subkelas menggunakan mekanisme MRO dalam berbilang warisan

Dalam Python, apabila mentakrifkan kelas, anda boleh menentukan kelas induknya. Subkelas mewarisi semua sifat dan kaedah kelas induknya dan boleh menambah sifat dan kaedah uniknya sendiri.

Walau bagaimanapun, jika kelas mempunyai berbilang kelas induk langsung, mungkin terdapat sifat dan kaedah dengan nama yang sama antara kelas induk ini. Untuk memanggil sifat dan kaedah ini dengan betul, Python menggunakan algoritma yang dipanggil "Perintah Resolusi Kaedah" (Perintah Resolusi Kaedah, MRO) untuk menentukan susunan carian sifat dan kaedah.

Prinsip algoritma

Dalam Python 2.x, MRO dilaksanakan menggunakan algoritma carian pertama mendalam (DFS). Terdapat beberapa masalah dengan algoritma ini yang menyebabkan urutan panggilan kaedah tidak dihuraikan dengan betul dalam beberapa kes. Contohnya:

class A:
    def foo(self):
        print("A.foo")

class B(A):
    pass

class C(A):
    def foo(self):
        print("C.foo")

class D(B, C):
    pass

d = D()
d.foo()  # 输出"A.foo",而不是"C.foo"

Dalam kod di atas, kelas D mewarisi kelas B dan kelas C, dan kelas C mengatasi kaedah foo() kelas A. Oleh itu, apabila memanggil kaedah foo() objek d, secara teorinya kaedah foo() dalam kelas C harus dipanggil dahulu. Walau bagaimanapun, memandangkan Python 2.x menggunakan algoritma DFS, ia akan merentasi kelas B dahulu, kemudian kelas C, dan akhirnya kelas A. Oleh itu, kaedah foo() dalam kelas A akhirnya dipanggil, bukan kaedah foo() dalam kelas C.

Untuk menyelesaikan masalah ini, Python 2.3 memperkenalkan algoritma C3, yang menggunakan algoritma pengisihan topologi untuk mengira senarai MRO bagi memastikan ketepatan semasa memanggil kaedah. Prinsip asas algoritma C3 adalah seperti berikut:

  • Senarai MRO kelas gaya baharu (iaitu, kelas yang secara eksplisit mewarisi objek atau mewarisi objek secara tersirat) dikira mengikut algoritma carian luas-pertama (BFS).

  • Untuk setiap kelas, senarai MROnya hendaklah memenuhi tiga syarat berikut:

    • Senarai MRO subkelas hendaklah diberi kedudukan Pada hadapan senarai MRO kelas induk.

    • Jika dua kelas induk muncul dalam senarai MRO kelas anak, susunan relatif mereka dalam senarai adalah sama dengan penampilan mereka dalam kelas induk terdekat kelas anak pesanan adalah sama.

    • Sesuatu kelas tidak boleh muncul lebih daripada dua kali dalam senarai MROnya.

Algoritma ini boleh mengendalikan situasi dalam contoh kod di atas dengan betul, dengan itu memastikan ketepatan semasa memanggil kaedah.

Lihat senarai MRO

Dalam Python 3, anda boleh melihat senarai MRO kelas melalui atribut __mro__. Contohnya:

class A:
    def foo(self):
        print("A.foo")

class B(A):
    pass

class C(A):
    def foo(self):
        print("C.foo")

class D(B, C):
    pass

print(D.__mro__)

Hasil output ialah:

(7ac763e0e3c412ac905a46c6416e04f5, d3d10dde313d07caf2874a0faa31cc27, < ;kelas '__main__.C'>, d65e71c32c2035ca4f3e3c46100a7a5f, 54a102a043f87e42c8336ea7b96e6d95)

di mana, 2c80631a2a60f09db0db08b479b83c38 mewakili kelas D itu sendiri, 8d660e54b264e36727cf2fd8e79d0fc1 dan 7ab913e23eec5fc1819bf61fa9f4a7de masing-masing mewakili kelas induk B dan C kelas D, 2282f191c7bda9371fce73ccb964a6ec mewakili kelas induk biasa A kelas B dan C, dan 0e122eba0a2a294242e197bbe224b40e mewakili kelas asas semua kelas gaya baharu . Susunan senarai ini ialah susunan sifat dan kaedah dicari apabila Python sedang berjalan.

Atas ialah kandungan terperinci Bagaimanakah subkelas python menggunakan MRO dalam pelbagai warisan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam