Question

Si j'ai du code Python

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

et j'ai cours C, existe-t-il un moyen de parcourir ses super classes (A et B) ?Quelque chose comme un pseudocode :

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

Une solution semble être inspecter le module et getclasstree fonction.

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

mais est-ce une manière « pythonienne » d'atteindre l'objectif ?

Était-ce utile?

La solution

C.__bases__ est un tableau de super classes, vous pouvez donc implémenter votre fonction hypothétique comme ceci :

def magicGetSuperClasses(cls):
  return cls.__bases__

Mais j'imagine qu'il serait plus facile de simplement faire référence cls.__bases__ directement dans la plupart des cas.

Autres conseils

@John:Votre extrait ne fonctionne pas : vous renvoyez le classe des classes de base (également appelées métaclasses).Tu veux vraiment juste 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

De plus, si vous utilisez Python 2.4+, vous pouvez utiliser expressions génératrices au lieu de créer une liste (via []), puis de la transformer en tuple (via tuple).Par exemple:

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

C'est un exemple quelque peu déroutant, mais les genexps sont généralement faciles et sympas.:)

Le module d'inspection était un bon début, utilisez le obtenirmro fonction:

Renvoie un tuple des classes de base de la classe cls, y compris cls, dans l'ordre de résolution des méthodes.Aucune classe n'apparaît plus d'une fois dans ce tuple....

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

Le premier élément du tuple renvoyé est C, vous pouvez simplement l'ignorer.

si vous avez besoin de savoir dans quel ordre super() appellerait les classes que vous pouvez utiliser C.__mro__ et je n'ai pas besoin inspect donc.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top