Pregunta

Si tengo código Python

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

y tengo clase C, ¿hay alguna manera de iterar a través de su superclase (A y B)?Algo así como pseudocódigo:

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

Una solución parece ser inspeccionar el módulo y getclasstree función.

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

¿Pero es esta una forma "pitoniana" de lograr el objetivo?

¿Fue útil?

Solución

C.__bases__ es una matriz de superclases, por lo que podrías implementar tu función hipotética de esta manera:

def magicGetSuperClasses(cls):
  return cls.__bases__

Pero imagino que sería más fácil simplemente hacer referencia cls.__bases__ directamente en la mayoría de los casos.

Otros consejos

@John:Su fragmento no funciona: está devolviendo el clase de las clases base (que también se conocen como metaclases).Realmente solo quieres 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

Además, si estás usando Python 2.4+ puedes usar expresiones generadoras en lugar de crear una lista (a través de []), y luego convertirla en una tupla (a través de tuple).Por ejemplo:

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

Este es un ejemplo un tanto confuso, pero las genexps son generalmente fáciles y interesantes.:)

El módulo de inspección fue un buen comienzo, use el getmro función:

Devuelve una tupla de las clases base de la clase cls, incluida cls, en el orden de resolución del método.Ninguna clase aparece más de una vez en esta tupla....

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

El primer elemento de la tupla devuelta es C, puedes simplemente ignorarlo.

si necesita saber para ordenar en qué super() llamaría a las clases que puede usar C.__mro__ y no necesito inspect por lo tanto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top