J'ai vu de nombreux exemples de personnes extrayant toutes les classes d'un module, généralement quelque chose comme:
# foo.py
class Foo:
pass
# test.py
import inspect
import foo
for name, obj in inspect.getmembers(foo):
if inspect.isclass(obj):
print obj
Impressionnant.
Mais je ne peux pas savoir comment obtenir toutes les classes du module actuel .
# foo.py
import inspect
class Foo:
pass
def print_classes():
for name, obj in inspect.getmembers(???): # what do I do here?
if inspect.isclass(obj):
print obj
# test.py
import foo
foo.print_classes()
C'est probablement quelque chose de vraiment évident, mais je n'ai rien trouvé. Quelqu'un peut m'aider?
python
reflection
inspect
mcccclean
la source
la source
"class"
? Pourquoi ça ne marche pas?Réponses:
Essaye ça:
Dans votre contexte:
Et encore mieux:
Parce que
inspect.getmembers()
prend un prédicat.la source
from optparse import OptionParser
), ces modules sont inclus dans la liste d'impression. Comment pourrais-je éviter cela?inspect.getmembers(sys.modules[__name__], lambda member: member.__module__ == __name__ and isnpect.isclass)
dict(inspect.getmembers(sys.modules[__name__])) == globals()
est toujoursTrue
, alors pourquoi les importations?inspect.getmembers(sys.modules[__name__], lambda member: inspect.isclass(member) and member.__module__ == __name__
isclass
.Qu'en est-il de
?
la source
isinstance(obj, types.ClassType)
pudb
exécution de votre programme de cette façon, entraînent une interruptionsys.modules
aléatoire du code lors du débogage.globals()
semble un peu moche, mais il semble être beaucoup plus fiable.Je ne sais pas s'il y a une façon «correcte» de le faire, mais votre extrait est sur la bonne voie: ajoutez simplement
import foo
à foo.py, doinspect.getmembers(foo)
, et cela devrait fonctionner correctement .la source
J'ai pu obtenir tout ce dont j'avais besoin grâce au plus
dir
intégrégetattr
.Cependant, cela ressemble à une boule de poils:
la source
Notez que le module de navigateur de classe Python de stdlib utilise l'analyse de source statique, donc il ne fonctionne que pour les modules qui sont sauvegardés par un vrai
.py
fichier.la source
Si vous voulez avoir toutes les classes qui appartiennent au module courant, vous pouvez utiliser ceci:
Si vous utilisez la réponse de Nadia et que vous importiez d'autres classes sur votre module, ces classes seront également importées.
C'est pourquoi
member.__module__ == __name__
est ajouté au prédicat utilisé suris_class_member
. Cette instruction vérifie que la classe appartient vraiment au module.Un prédicat est une fonction (appelable), qui renvoie une valeur booléenne.
la source
Une autre solution qui fonctionne en Python 2 et 3:
la source
C'est la ligne que j'utilise pour obtenir toutes les classes qui ont été définies dans le module actuel (c'est-à-dire non importées). C'est un peu long selon PEP-8 mais vous pouvez le changer comme bon vous semble.
Cela vous donne une liste des noms de classe. Si vous voulez que les objets de classe eux-mêmes conservent simplement obj à la place.
Cela a été plus utile dans mon expérience.
la source
la source
Je pense que vous pouvez faire quelque chose comme ça.
si vous avez besoin de vos propres cours
la source
Je me retrouve fréquemment à écrire des utilitaires de ligne de commande dans lesquels le premier argument est destiné à faire référence à l'une des nombreuses classes différentes. Par exemple
./something.py feature command —-arguments
, oùFeature
est une classe etcommand
est une méthode sur cette classe. Voici une classe de base qui rend cela facile.L'hypothèse est que cette classe de base réside dans un répertoire à côté de toutes ses sous-classes. Vous pouvez ensuite appeler
ArgBaseClass(foo = bar).load_subclasses()
qui renverra un dictionnaire. Par exemple, si le répertoire ressemble à ceci:En supposant des
feature.py
implémentationsclass Feature(ArgBaseClass)
, l'invocation ci-dessus deload_subclasses
retourne{ 'feature' : <Feature object> }
. Le mêmekwargs
(foo = bar
) sera passé dans laFeature
classe.la source