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

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

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.

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!


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.


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

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.