46 votes

Python : trouver toutes les classes qui héritent de celle-ci ?

Existe-t-il un moyen en python d'interroger un espace de noms pour les classes qui héritent d'une classe particulière ? Étant donné une classe widget j'aimerais pouvoir appeler quelque chose comme inheritors(widget) pour obtenir une liste de tous mes différents types de widgets.

71voto

Duncan Points 25356

Vous souhaitez utiliser Widget.__subclasses__() pour obtenir une liste de toutes les sous-classes. Il ne recherche que les sous-classes directes, donc si vous les voulez toutes, vous devrez faire un peu plus de travail :

 def inheritors(klass):
    subclasses = set()
    work = [klass]
    while work:
        parent = work.pop()
        for child in parent.__subclasses__():
            if child not in subclasses:
                subclasses.add(child)
                work.append(child)
    return subclasses

NB Si vous utilisez Python 2.x, cela ne fonctionne que pour les classes de nouveau style.

20voto

Imran Points 20117

Vous pouvez suivre l'héritage avec votre propre métaclasse

 import collections

class A(object):
    class __metaclass__(type):
        __inheritors__ = defaultdict(list)

        def __new__(meta, name, bases, dct):
            klass = type.__new__(meta, name, bases, dct)
            for base in klass.mro()[1:-1]:
                meta.__inheritors__[base].append(klass)
            return klass

class B(A):
    pass

class C(B):
    pass

>>> A.__inheritors__
defaultdict(<type 'list'>, {<class '__main__.A'>: [<class '__main__.B'>, <class '__main__.C'>], <class '__main__.B'>: [<class '__main__.C'>]})

Tout ce qui est hérité de A ou de ses classes dérivées sera suivi. Vous obtiendrez une carte d'héritage complète lorsque tous les modules de votre application seront chargés.

1voto

Andreas Jung Points 1

Vous devez parcourir tous les objets de l'espace de noms global (globals()) et vérifier si l'objet/la classe associé est une sous-classe d'une autre classe (consultez la documentation Python pour issubclass()).

1voto

formiaczek Points 89
# return list of tuples (objclass, name) containing all subclasses in callers' module
def FindAllSubclasses(classType):
    import sys, inspect
    subclasses = []
    callers_module = sys._getframe(1).f_globals['__name__']
    classes = inspect.getmembers(sys.modules[callers_module], inspect.isclass)
    for name, obj in classes:
        if (obj is not classType) and (classType in inspect.getmro(obj)):
            subclasses.append((obj, name))
    return subclasses

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X