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'>)

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>]

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.

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!


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.


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

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.

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.