Bagaimanakah subkelas python menggunakan MRO dalam pelbagai warisan?

WBOY
Lepaskan: 2023-04-19 18:19:13
ke hadapan
1544 orang telah melayarinya

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"
Salin selepas log masuk

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__)
Salin selepas log masuk

Hasil output ialah:

(, , < ;kelas '__main__.C'>, , )

di mana, <class &#39;__main__.D&#39;> mewakili kelas D itu sendiri, <class &#39;__main__.B&#39;> dan <class &#39;__main__.C&#39;> masing-masing mewakili kelas induk B dan C kelas D, <class &#39;__main__.A&#39;> mewakili kelas induk biasa A kelas B dan C, dan <class &#39;object&#39;> 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!

Label berkaitan:
sumber:yisu.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan