Daftar semua kelas dasar dalam hierarki kelas yang diberikan?

Jawaban:

196

inspect.getmro(cls)bekerja untuk kelas gaya baru dan lama dan mengembalikan sama dengan NewClass.mro(): daftar kelas dan semua kelas leluhurnya, dalam urutan yang digunakan untuk resolusi metode.

>>> class A(object):
>>>     pass
>>>
>>> class B(A):
>>>     pass
>>>
>>> import inspect
>>> inspect.getmro(B)
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
Jochen Ritzel
sumber
2
Tidak berfungsi untuk kelas pyobjc :( File "/ Pengguna / rbp/Projects/zzzzzzz/macmdtypes.py", baris 70, dalam print coece inspect.getmro (path) File "/System/Library/Frameworks/Python.framework/ Versi / 2.7 / lib / python2.7 / inspect.py ", baris 348, di getmro searchbases (cls, result) File" /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect .py ", baris 339, dalam _searchbases untuk basis di cls .__ bases_ : AttributeError: objek ' NSTaggedDate' tidak memiliki atribut '__bases '
rbp
17
@rbp Saya menduga bahwa Anda memiliki masalah yang sama yang saya temui: Anda coba lakukan inspect.getmro(obj)bukan inspect.getmro(type(obj)).
esmit
44

Lihat __bases__properti yang tersedia di python class, yang berisi tuple kelas pangkalan:

>>> def classlookup(cls):
...     c = list(cls.__bases__)
...     for base in c:
...         c.extend(classlookup(base))
...     return c
...
>>> class A: pass
...
>>> class B(A): pass
...
>>> class C(object, B): pass
...
>>> classlookup(C)
[<type 'object'>, <class __main__.B at 0x00AB7300>, <class __main__.A at 0x00A6D630>]
Crescent Fresh
sumber
5
Ini dapat menyebabkan duplikat. Dan inilah mengapa dokumentasi untuk getmrosecara eksplisit mengatakan "Tidak ada kelas yang muncul lebih dari satu kali dalam tuple ini"?
Sridhar Ratnakumar
10
Perhatian, __bases__hanya naik satu level . (Seperti utilitas rekursif Anda menyiratkan, tetapi pandangan sekilas pada contoh mungkin tidak mengambil itu.)
Bob Stein
32

inspect.getclasstree()akan membuat daftar kelas dan basisnya. Pemakaian:

inspect.getclasstree(inspect.getmro(IOError)) # Insert your Class instead of IOError.
Ned Batchelder
sumber
1
Ooh bagus Dan untuk hasil yang lebih bagus, gunakan cetak! python -c 'import inspect; from pprint import pprint as pp; pp(inspect.getclasstree(inspect.getmro(IOError)))'
penguin359
20

Anda bisa menggunakan __bases__tuple dari objek kelas:

class A(object, B, C):
    def __init__(self):
       pass
print A.__bases__

Tuple yang dikembalikan oleh __bases__memiliki semua kelas dasarnya.

Semoga ini bisa membantu!

mandel
sumber
Jika kelas Anda mewarisi dari kelas yang mewarisi dari kelas, hanya bagian pertama dari rantai yang akan ada di dalamnya__bases__
Boris
Sederhana dan bersih tanpa mengimpor seluruh modul untuk satu fungsi.
Temperosa
8

Di python 3.7 Anda tidak perlu mengimpor inspect, type.mro akan memberi Anda hasilnya.

>>> class A:
...   pass
... 
>>> class B(A):
...   pass
... 
>>> type.mro(B)
[<class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
>>>

perhatikan bahwa dengan python 3.x setiap kelas mewarisi dari kelas objek dasar.

Serjik
sumber
8

Menurut dokumen Python , kita juga bisa menggunakan class.__mro__atribut atau class.mro()metode:

>>> class A:
...     pass
... 
>>> class B(A):
...     pass
... 
>>> B.__mro__
(<class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
>>> A.__mro__
(<class '__main__.A'>, <class 'object'>)
>>> object.__mro__
(<class 'object'>,)
>>>
>>> B.mro()
[<class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
>>> A.mro()
[<class '__main__.A'>, <class 'object'>]
>>> object.mro()
[<class 'object'>]
>>> A in B.mro()
True
YaOzI
sumber
2

Meskipun jawaban Jochen sangat membantu dan benar, karena Anda dapat memperoleh hierarki kelas menggunakan metode .getmro () pada modul inspect, penting juga untuk menyoroti bahwa hierarki warisan Python adalah sebagai berikut:

ex:

class MyClass(YourClass):

Kelas warisan

  • Kelas anak-anak
  • Kelas turunan
  • Subkelas

ex:

class YourClass(Object):

Kelas yang diwarisi

  • Kelas induk
  • Kelas dasar
  • Superclass

Satu kelas dapat mewarisi dari yang lain - Kelas yang diatribusikan diwarisi - khususnya, metodenya diwarisi - ini berarti bahwa instance dari kelas pewarisan (anak) dapat mengakses yang dikaitkan dengan kelas yang diwarisi (induk)

instance -> class -> kemudian kelas yang diwarisi

menggunakan

import inspect
inspect.getmro(MyClass)

akan menunjukkan kepada Anda hierarki, dalam Python.

Carson
sumber