J'ai vu beaucoup d'exemples de personnes extraire 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 trouver comment obtenir toutes les classes du module current .
# 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 très évident, mais je n'ai rien trouvé. Quelqu'un peut m'aider?
Essaye ça:
import sys
current_module = sys.modules[__name__]
Dans votre contexte:
import sys, inspect
def print_classes():
for name, obj in inspect.getmembers(sys.modules[__name__]):
if inspect.isclass(obj):
print(obj)
Et encore mieux:
clsmembers = inspect.getmembers(sys.modules[__name__], inspect.isclass)
Parce que inspect.getmembers()
prend un prédicat.
Qu'en est-il de
g = globals().copy()
for name, obj in g.iteritems():
?
Je ne sais pas s'il existe un moyen «approprié» de le faire, mais votre extrait de code est sur la bonne voie: ajoutez simplement import foo
à foo.py, faites inspect.getmembers(foo)
et cela devrait fonctionner correctement.
J'ai pu obtenir tout ce dont j'avais besoin dans dir
construit plus getattr
.
# Works on pretty much everything, but be mindful that
# you get lists of strings back
print dir(myproject)
print dir(myproject.mymodule)
print dir(myproject.mymodule.myfile)
print dir(myproject.mymodule.myfile.myclass)
# But, the string names can be resolved with getattr, (as seen below)
Bien que cela ressemble à une boule de poils:
def list_supported_platforms():
"""
List supported platforms (to match sys.platform)
@Retirms:
list str: platform names
"""
return list(itertools.chain(
*list(
# Get the class's constant
getattr(
# Get the module's first class, which we wrote
getattr(
# Get the module
getattr(platforms, item),
dir(
getattr(platforms, item)
)[0]
),
'SYS_PLATFORMS'
)
# For each include in platforms/__init__.py
for item in dir(platforms)
# Ignore magic, ourselves (index.py) and a base class.
if not item.startswith('__') and item not in ['index', 'base']
)
))
import pyclbr
print(pyclbr.readmodule(__name__).keys())
Notez que le module de navigation de classe Python de stdlib utilise une analyse de source statique, de sorte qu'il ne fonctionne que pour les modules sauvegardés par un fichier .py
réel.
Si vous voulez avoir toutes les classes qui appartiennent au module actuel, vous pouvez utiliser ceci:
import sys, inspect
def print_classes():
is_class_member = lambda member: inspect.isclass(member) and member.__module__ == __name__
clsmembers = inspect.getmembers(sys.modules[__name__], is_class_member)
Si vous utilisez la réponse de Nadia et que vous importez d'autres classes de votre module, ces classes seront également importées.
C'est pourquoi member.__module__ == __name__
est ajouté au prédicat utilisé sur is_class_member
. Cette déclaration vérifie que la classe appartient vraiment au module.
Un prédicat est une fonction (appelable) qui renvoie une valeur booléenne.
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). Selon PEP-8, c'est un peu long, mais vous pouvez le changer à votre guise.
import sys
import inspect
classes = [name for name, obj in inspect.getmembers(sys.modules[__name__], inspect.isclass)
if obj.__module__ is __name__]
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.
classes = [obj for name, obj in inspect.getmembers(sys.modules[__name__], inspect.isclass)
if obj.__module__ is __name__]
Cela a été plus utile dans mon expérience.
Une autre solution qui fonctionne en Python 2 et 3:
#foo.py
import sys
class Foo(object):
pass
def print_classes():
current_module = sys.modules[__name__]
for key in dir(current_module):
if isinstance( getattr(current_module, key), type ):
print(key)
# test.py
import foo
foo.print_classes()
Je pense que vous pouvez faire quelque chose comme ça.
class custom(object):
__custom__ = True
class Alpha(custom):
something = 3
def GetClasses():
return [x for x in globals() if hasattr(globals()[str(x)], '__custom__')]
print(GetClasses())`
si vous avez besoin de cours particuliers