Liste toutes les classes de base dans une hiérarchie de classe donnée?

Réponses:

196

inspect.getmro(cls)fonctionne pour les classes de style nouvelles et anciennes et renvoie la même chose que NewClass.mro(): une liste de la classe et de toutes ses classes ancêtres, dans l'ordre utilisé pour la résolution de la méthode.

>>> class A(object):
>>>     pass
>>>
>>> class B(A):
>>>     pass
>>>
>>> import inspect
>>> inspect.getmro(B)
(<class '__main__.B'>, <class '__main__.A'>, <type 'object'>)
Jochen Ritzel
la source
2
Ne fonctionne pas pour les classes pyobjc :( File "/Users/rbp/Projects/zzzzzzz/macmdtypes.py", ligne 70, en coerce print inspect.getmro (path) File "/System/Library/Frameworks/Python.framework/ Versions / 2.7 / lib / python2.7 / inspect.py ", ligne 348, dans getmro searchbases (cls, result) File" /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/inspect .py ", ligne 339, dans _searchbases for base in cls .__ bases_ : AttributeError: l'objet ' NSTaggedDate' n'a pas d'attribut '__bases '
rbp
17
@rbp Je soupçonne que vous avez eu le même problème que celui que j'ai rencontré: vous essayiez de faire inspect.getmro(obj)au lieu de inspect.getmro(type(obj)).
esmettre le
44

Voir la __bases__propriété disponible sur un python class, qui contient un tuple des classes de 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>]
Croissant frais
la source
5
Cela peut introduire des doublons. Et c'est pourquoi la documentation de getmrodit explicitement "Aucune classe n'apparaît plus d'une fois dans ce tuple"?
Sridhar Ratnakumar le
10
Attention, __bases__ne monte que d' un niveau . (Comme votre utilitaire récursif l'indique, mais un coup d'œil rapide sur l'exemple pourrait ne pas comprendre cela.)
Bob Stein
32

inspect.getclasstree()créera une liste imbriquée de classes et de leurs bases. Usage:

inspect.getclasstree(inspect.getmro(IOError)) # Insert your Class instead of IOError.
Ned Batchelder
la source
1
Ooh bien. Et pour une sortie encore plus agréable, utilisez pprint! python -c 'import inspect; from pprint import pprint as pp; pp(inspect.getclasstree(inspect.getmro(IOError)))'
penguin359
20

vous pouvez utiliser le __bases__tuple de l'objet de classe:

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

Le tuple retourné par __bases__a toutes ses classes de base.

J'espère que ça aide!

Mandel
la source
Si votre classe hérite d'une classe qui hérite d'une classe, seule la première partie de la chaîne sera dans son__bases__
Boris
Simple et propre sans importer un module entier pour une seule fonction.
Temperosa
8

En python 3.7, vous n'avez pas besoin d'importer inspect, type.mro vous donnera le résultat.

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

attention, en python 3.x, chaque classe hérite de la classe d'objet de base.

Serjik
la source
8

Selon la documentation Python , nous pouvons également simplement utiliser un class.__mro__attribut ou une class.mro()méthode:

>>> 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
YaOzI
la source
2

Bien que la réponse de Jochen soit très utile et correcte, comme vous pouvez obtenir la hiérarchie des classes en utilisant la méthode .getmro () du module inspect, il est également important de souligner que la hiérarchie d'héritage de Python est la suivante:

ex:

class MyClass(YourClass):

Une classe héritière

  • Classe enfant
  • Classe dérivée
  • Sous-classe

ex:

class YourClass(Object):

Une classe héritée

  • Classe parent
  • Classe de base
  • Superclasse

Une classe peut hériter d'une autre - La classe 'attribuée est héritée - en particulier, ses méthodes sont héritées - cela signifie que les instances d'une classe (enfant) héritière peuvent accéder à l'attribut de la classe (parent) héritée

instance -> classe -> classes héritées

en utilisant

import inspect
inspect.getmro(MyClass)

vous montrera la hiérarchie, dans Python.

Carson
la source