Alle Basisklassen in einer Hierarchie der angegebenen Klasse auflisten?

Antworten:

196

inspect.getmro(cls)Funktioniert sowohl für Klassen im neuen als auch im alten Stil und gibt dasselbe zurück wie NewClass.mro(): eine Liste der Klasse und aller ihrer Vorfahrenklassen in der Reihenfolge, in der die Methodenauflösung verwendet wird.

>>> class A(object):
>>>     pass
>>>
>>> class B(A):
>>>     pass
>>>
>>> import inspect
>>> inspect.getmro(B)
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
Jochen Ritzel
quelle
2
Funktioniert nicht für pyobjc-Klassen :( Datei "/Users/rbp/Projects/zzzzzzz/macmdtypes.py", Zeile 70, in coerce print inspect.getmro (Pfad) Datei "/System/Library/Frameworks/Python.framework/ Versionen / 2.7 / lib / python2.7 / inspect.py ", Zeile 348, in der Datei" getmro searchbases (cls, result) "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect .py ", Zeile 339, in _searchbases for base in cls .__ base_ : AttributeError: ' NSTaggedDate'-Objekt hat kein Attribut' __bases '
rbp
17
@rbp Ich vermute, dass Sie das gleiche Problem hatten, auf das ich gestoßen bin: Sie haben versucht, es zu tun, inspect.getmro(obj)anstatt inspect.getmro(type(obj)).
Esmit
44

Sehen Sie sich die __bases__Eigenschaft an class, die für eine Python verfügbar ist , die ein Tupel der Basisklassen enthält:

>>> 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>]
Halbmond frisch
quelle
5
Dies kann zu Duplikaten führen. Und deshalb heißt es in der Dokumentation getmroexplizit "Keine Klasse erscheint mehr als einmal in diesem Tupel"?
Sridhar Ratnakumar
10
Achtung, __bases__geht nur eine Ebene höher . (Wie Ihr rekursives Dienstprogramm andeutet, aber ein flüchtiger Blick auf das Beispiel könnte dies nicht aufgreifen.)
Bob Stein
32

inspect.getclasstree()erstellt eine verschachtelte Liste der Klassen und ihrer Basen. Verwendung:

inspect.getclasstree(inspect.getmro(IOError)) # Insert your Class instead of IOError.
Ned Batchelder
quelle
1
Oh, schön. Und für eine noch schönere Ausgabe verwenden Sie pprint! python -c 'import inspect; from pprint import pprint as pp; pp(inspect.getclasstree(inspect.getmro(IOError)))'
Pinguin359
20

Sie können das __bases__Tupel des Klassenobjekts verwenden:

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

Das von zurückgegebene Tupel __bases__hat alle seine Basisklassen.

Ich hoffe es hilft!

Mandel
quelle
Wenn Ihre Klasse von einer Klasse erbt, die von einer Klasse erbt, befindet sich nur der erste Teil der Kette in ihrer__bases__
Boris
Einfach und sauber, ohne ein ganzes Modul für eine einzelne Funktion zu importieren.
Temperosa
8

In Python 3.7 müssen Sie inspect nicht importieren. Type.mro gibt Ihnen das Ergebnis.

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

Beachten Sie, dass in Python 3.x jede Klasse von der Basisobjektklasse erbt.

Serjik
quelle
8

Laut Python-Dokument können wir auch einfach class.__mro__Attribute oder class.mro()Methoden verwenden:

>>> 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
quelle
2

Obwohl Jochens Antwort sehr hilfreich und richtig ist, da Sie die Klassenhierarchie mit der .getmro () -Methode des Inspect-Moduls erhalten können, ist es auch wichtig hervorzuheben, dass die Vererbungshierarchie von Python wie folgt lautet:

Ex:

class MyClass(YourClass):

Eine erbende Klasse

  • Kinderklasse
  • Abgeleitete Klasse
  • Unterklasse

Ex:

class YourClass(Object):

Eine geerbte Klasse

  • Übergeordnete Klasse
  • Basisklasse
  • Superklasse

Eine Klasse kann von einer anderen erben - Die zugewiesenen Klassen werden geerbt - insbesondere werden ihre Methoden vererbt - dies bedeutet, dass Instanzen einer ererbenden (untergeordneten) Klasse auf die der geerbten (übergeordneten) Klasse zugeschriebenen zugreifen können

Instanz -> Klasse -> dann geerbte Klassen

mit

import inspect
inspect.getmro(MyClass)

zeigt Ihnen die Hierarchie in Python.

Carson
quelle