Frage

Wenn ich Python-code

class A():
    pass
class B():
    pass
class C(A, B):
    pass

und ich habe Klasse C, gibt es eine Möglichkeit zu Durchlaufen und es ist super eingestuft (A und B)?So etwas wie pseudocode:

>>> magicGetSuperClasses(C)
(<type 'A'>, <type 'B'>)

Eine Lösung scheint es zu sein inspect-Modul und getclasstree Funktion.

def magicGetSuperClasses(cls):
    return [o[0] for o in inspect.getclasstree([cls]) if type(o[0]) == type]

aber ist das ein "Pythonian" Weg, um das Ziel zu erreichen?

War es hilfreich?

Lösung

C.__bases__ ist ein array der super-Klassen, so können Sie setzen Ihre hypothetische Funktion etwa so:

def magicGetSuperClasses(cls):
  return cls.__bases__

Aber ich Stelle mir vor, es wäre einfacher, einfach Referenz cls.__bases__ direkt in den meisten Fällen.

Andere Tipps

@John:Das snippet funktioniert nicht -- sind Sie wieder, die Klasse der Basis-Klassen (auch bekannt als Metaklassen).Sie wirklich will nur cls.__bases__:

class A: pass
class B: pass
class C(A, B): pass

c = C() # Instance

assert C.__bases__ == (A, B) # Works
assert c.__class__.__bases__ == (A, B) # Works

def magicGetSuperClasses(clz):
  return tuple([base.__class__ for base in clz.__bases__])

assert magicGetSuperClasses(C) == (A, B) # Fails

Auch, wenn Sie mit Python 2.4+, die Sie verwenden können generator-Ausdrücke anstatt eine Liste mit (über []), drehen Sie dann in ein Tupel (via tuple).Zum Beispiel:

def get_base_metaclasses(cls):
    """Returns the metaclass of all the base classes of cls."""
    return tuple(base.__class__ for base in clz.__bases__)

Das ist ein wenig verwirrend, aber genexps sind in der Regel einfach und cool.:)

Die inspect-Modul war ein guter start, verwenden Sie die getmro Funktion:

Return a tuple Klasse cls Basis von Klassen, einschließlich der cls in Methode Auflösung um.Keine Klasse erscheint mehr als einmal in diesem Tupel....

>>> class A: pass
>>> class B: pass
>>> class C(A, B): pass
>>> import inspect
>>> inspect.getmro(C)[1:]
(<class __main__.A at 0x8c59f2c>, <class __main__.B at 0x8c59f5c>)

Das erste element des zurückgegebenen Tupel ist C, Sie können ignorieren es.

wenn Sie wissen müssen, um in die super() aufrufen würde, die Klassen, die Sie verwenden können C.__mro__ und brauchen nicht inspect daher.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top