2009-09-09 9 views
89

Étant donné une classe Foo (que ce soit une classe new-style ou non), comment générer toutes les classes de toutes les classes de base - n'importe où dans la hiérarchie d'héritage - issubclass?Liste toutes les classes de base dans une hiérarchie de classe donnée?

+1

Étant donné un objet de classe ('type' serait le meilleur terme)' isinstance' ne fonctionnera pas ... soit vous voulez dire 'issubclass' ou vous voulez prendre une instance ;-p –

+0

Merci; J'ai édité le post. –

Répondre

127

inspect.getmro(cls) œuvres pour les deux classes de style anciens et nouveaux et retourne le même 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'>) 
+1

Bravo: http://docs.python.org/library/inspect.html#inspect.getmro –

+1

Ne fonctionne pas pour les classes PyObjC :( fichier "/Users/rbp/Projects/zzzzzzz/macmdtypes.py", ligne 70, en coerce impression inspect.getmro (chemin) fichier « /System/Library/Frameworks/Python.framework/ Versions/2.7/lib/python2.7/inspect.py ", ligne 348, dans getmro _searchbases (cls, résultat) Fichier" /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7 /inspect.py ", ligne 339, dans _searchbases pour la base dans les bases .__Clés__: AttributeError: l'objet '__NSTaggedDate' n'a pas d'attribut '__bases__' – rbp

+7

@rbp pect que vous avez eu le même problème que j'ai rencontré: vous essayiez de faire 'inspect.getmro (obj)' au lieu de 'inspect.getmro (type (obj))'. – esmit

13

vous pouvez utiliser le __bases__ tuple de l'objet de classe:

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

tuple retourné par __bases__ a toutes ses classes de base.

J'espère que ça aide!

24

inspect.getclasstree() va créer une liste imbriquée de classes et leurs bases. Utilisation:

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

Oh, bien. Et pour une sortie encore plus agréable, utilisez pprint! "python -c" import inspect; de pprint import pprint en pp; pp (inspect.getclasstree (inspect.getmro (IOError))) ' – penguin359

28

Voir la __bases__ property disponible sur un python class, qui contient un tuple des bases des classes:

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

Ceci peut introduire des doublons. Et c'est pourquoi la documentation de 'getmro' dit explicitement" Aucune classe n'apparaît plus d'une fois dans ce tuple "? –

+2

Attention, '__bases__' monte seulement ** d'un niveau **. (Comme le suggère votre utilité récursive, mais un rapide coup d'œil sur l'exemple pourrait ne pas prendre en compte cela.) –

1

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

ex:

class MyClass(YourClass): 

Une classe héritant

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

ex:

class YourClass(Object): 

Une classe héritée

  • Parent classe
  • classe de base
  • Superclass

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

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

utilisant

import inspect 
inspect.getmro(MyClass) 

vous montrer la hiérarchie, au sein de Python.

Questions connexes