¿Enumerar todas las clases base en una jerarquía de clase dada?


Respuestas:


196

inspect.getmro(cls)funciona para las clases de estilo nuevas y antiguas y devuelve lo mismo que NewClass.mro(): una lista de la clase y todas sus clases ancestrales, en el orden utilizado para la resolución del método.

>>> class A(object):
>>>     pass
>>>
>>> class B(A):
>>>     pass
>>>
>>> import inspect
>>> inspect.getmro(B)
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)

2
No funciona para las clases pyobjc :( Archivo "/Users/rbp/Projects/zzzzzzz/macmdtypes.py", línea 70, en coerce print inspect.getmro (ruta) Archivo "/System/Library/Frameworks/Python.framework/ Versiones / 2.7 / lib / python2.7 / inspect.py ", línea 348, en bases de búsqueda getmro (cls, resultado) Archivo" /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect .py ", línea 339, en _searchbases para base en cls .__ bases_ : AttributeError: el objeto ' NSTaggedDate' no tiene atributo '__bases '
rbp

17
@rbp Sospecho que tuvo el mismo problema que encontré: estaba intentando hacerlo en inspect.getmro(obj)lugar de hacerlo inspect.getmro(type(obj)).
esmit

44

Vea la __bases__propiedad disponible en una python class, que contiene una tupla de las clases base:

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

55
Esto puede introducir duplicados. ¿Y es por eso que la documentación para getmroexplícitamente dice "Ninguna clase aparece más de una vez en esta tupla"?
Sridhar Ratnakumar

10
Precaución, __bases__solo sube un nivel . (Como su utilidad recursiva implica, pero una mirada superficial al ejemplo podría no captar eso.)
Bob Stein

32

inspect.getclasstree()creará una lista anidada de clases y sus bases. Uso:

inspect.getclasstree(inspect.getmro(IOError)) # Insert your Class instead of IOError.

1
Ooh genial. Y para una salida aún mejor, ¡usa pprint! python -c 'import inspect; from pprint import pprint as pp; pp(inspect.getclasstree(inspect.getmro(IOError)))'
penguin359

20

puedes usar la __bases__tupla del objeto de clase:

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

La tupla devuelta por __bases__tiene todas sus clases base.

¡Espero eso ayude!


Si su clase hereda de una clase que hereda de una clase, solo la primera parte de la cadena estará en su__bases__
Boris

Simple y limpio sin importar un módulo completo para una sola función.
Temperosa

8

En python 3.7 no necesita importar inspeccionar, type.mro le dará el resultado.

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

atención que en python 3.x cada clase hereda de la clase de objeto base.


8

Según el documento de Python , también podemos simplemente usar el class.__mro__atributo o el class.mro()método:

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

Aunque la respuesta de Jochen es muy útil y correcta, ya que puede obtener la jerarquía de clases utilizando el método .getmro () del módulo de inspección, también es importante resaltar que la jerarquía de herencia de Python es la siguiente:

ex:

class MyClass(YourClass):

Una clase heredadora

  • Clase infantil
  • Clase derivada
  • Subclase

ex:

class YourClass(Object):

Una clase heredada

  • Clase de padres
  • Clase base
  • Superclase

Una clase puede heredar de otra: los atributos de la clase 'se heredan', en particular, sus métodos se heredan, esto significa que las instancias de una clase heredadora (secundaria) pueden acceder atribuidas a la clase heredada (principal)

instancia -> clase -> luego clases heredadas

utilizando

import inspect
inspect.getmro(MyClass)

le mostrará la jerarquía, dentro de Python.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.