Bagaimana cara mendapatkan orang tua dari kelas Python?


202

Bagaimana saya bisa mendapatkan kelas induk dari kelas Python?

Jawaban:


233

Gunakan atribut berikut:

cls.__bases__

Dari dokumen :

Tupel kelas dasar dari objek kelas.

Contoh:

>>> str.__bases__
(<type 'basestring'>,)

Contoh lain:

>>> class A(object):
...   pass
... 
>>> class B(object):
...   pass
... 
>>> class C(A, B):
...   pass
... 
>>> C.__bases__
(<class '__main__.A'>, <class '__main__.B'>)

1
Untuk mendapatkan basis dari objek instantiated lakukan type(C()).__bases__seperti yang disebutkan lebih lanjut di bawah ini
citynorman

106

Jika Anda menginginkan semua leluhur daripada yang langsung, gunakan inspect.getmro :

import inspect
print inspect.getmro(cls)

Berguna, ini memberi Anda semua kelas leluhur dalam "metode resolusi urutan" - yaitu urutan di mana leluhur akan diperiksa ketika menyelesaikan metode (atau, sebenarnya, atribut lainnya - metode dan atribut lainnya hidup di namespace yang sama dalam Python, setelah semua ;-).


34
Anda juga dapat menggunakan cls.__mro__(setidaknya dalam Python 3.5)
naught101

@ naught101, harap ubah menjadi jawaban lengkap. Saya hampir melewatkannya, dan begitu juga, saya pikir banyak orang lain.
Shihab Shahriar Khan

14

Kelas gaya baru memiliki metode mro yang dapat Anda panggil yang mengembalikan daftar kelas induk dalam urutan resolusi metode.


Apa yang dianggap sebagai kelas gaya baru? Sepertinya saya bisa menggunakan ini dengan model Django, tetapi apa pun yang hanya mewarisi dari objecttampaknya tidak merespons mro.
Brian Kung

1
mempertimbangkan objek x, kita bisa mendapatkan urutan resolusi metode dengan panggilan yang type(x).mro() dapat kita pertimbangkan jika xmemiliki ClassXsebagai kelas dasar dengan: ClassX in type(x).mro()
648trindade

13

Cara TERCEPAT , untuk melihat semua orang tua, dan DI ORDER , cukup gunakan built in__mro__

yaitu repr(YOUR_CLASS.__mro__)


>>>
>>>
>>> import getpass
>>> getpass.GetPassWarning.__mro__

output, DALAM PESANAN


(<class 'getpass.GetPassWarning'>, <type 'exceptions.UserWarning'>,
<type 'exceptions.Warning'>, <type 'exceptions.Exception'>, 
<type 'exceptions.BaseException'>, <type 'object'>)
>>>

Itu dia. Jawaban "terbaik" saat ini, memiliki 182 suara (saat saya mengetik ini) tetapi ini SO jauh lebih sederhana daripada beberapa yang berbelit-belit untuk loop, melihat ke basis pangkalan satu kelas pada suatu waktu, belum lagi ketika sebuah kelas memperpanjang DUA atau lebih induk kelas. Mengimpor dan menggunakan inspecthanya cloud cakupannya tidak perlu. Sejujurnya itu memalukan orang tidak tahu untuk hanya menggunakan built-in

Saya harap ini membantu!


@John Smith stackoverflow.com/users/139885/john-smith , saya harap Anda melihat jawaban ini. Jika Anda suka, beri tahu saya dengan suara keras!
PyTis

1
Bahkan, inspect.getmrohanya memanggil __mro__objek, seperti yang Anda lihat di github.com/python/cpython/blob/… . Menggunakan getmromenghasilkan kode yang lebih bersih dan lebih mudah dibaca. Meskipun melewatkan panggilan fungsi memang lebih cepat.
tna0y

9

Gunakan basis jika Anda hanya ingin mendapatkan orang tua, gunakan __mro__(seperti yang ditunjukkan oleh @ naught101) untuk mendapatkan urutan resolusi metode (jadi untuk mengetahui di mana urutan init dieksekusi).

Basis (dan pertama mendapatkan kelas untuk objek yang ada):

>>> some_object = "some_text"
>>> some_object.__class__.__bases__
(object,)

Untuk mro dalam versi Python terbaru:

>>> some_object = "some_text"
>>> some_object.__class__.__mro__
(str, object)

Jelas, ketika Anda sudah memiliki definisi kelas, Anda bisa langsung menyebutnya __mro__:

>>> class A(): pass
>>> A.__mro__
(__main__.A, object)

3

Jika Anda ingin memastikan mereka semua dipanggil, gunakan superdi semua level.


Setelah Anda menggunakan super, Anda harus menggunakannya di semua level, itulah sebabnya Anda harus mendokumentasikan penggunaannya secara eksplisit. Anda juga mungkin ingin tahu bahwa super tidak bekerja di setiap kelas ...
DasIch
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.