Est-il un moyen simple pour trouver tous les modules qui font partie d'un paquet python? J'ai trouvé ce vieux débat, qui n'est pas vraiment concluant, mais j'aimerais avoir une réponse définitive avant que je roule ma propre solution basée sur le système d'exploitation.listdir().
Réponses
Trop de publicités?Oui, vous voulez quelque chose de basé sur pkgutil
ou semblables, de cette façon, vous pouvez traiter tous les paquets semblables, peu importe si elles sont dans les œufs ou les fermetures à glissière ou so (où les os.listdir ne va pas aider).
import pkgutil
# this is the package we are inspecting -- for example 'email' from stdlib
import email
package = email
for importer, modname, ispkg in pkgutil.iter_modules(package.__path__):
print "Found submodule %s (is a package: %s)" % (modname, ispkg)
Comment les importer? Vous pouvez simplement utiliser __import__
comme d'habitude:
import pkgutil
# this is the package we are inspecting -- for example 'email' from stdlib
import email
package = email
prefix = package.__name__ + "."
for importer, modname, ispkg in pkgutil.iter_modules(package.__path__, prefix):
print "Found submodule %s (is a package: %s)" % (modname, ispkg)
module = __import__(modname, fromlist="dummy")
print "Imported", module
Le bon outil pour ce travail, c'est pkgutil.walk_packages.
La liste de tous les modules de votre système:
import pkgutil
for importer, modname, ispkg in pkgutil.walk_packages(path=None, onerror=lambda x: None):
print(modname)
Sachez que walk_packages les importations de tous les sous-paquets, mais pas submodules.
Si vous souhaitez la liste de tous les submodules d'un certain paquet, vous pouvez utiliser quelque chose comme ceci:
import pkgutil
import scipy
package=scipy
for importer, modname, ispkg in pkgutil.walk_packages(path=package.__path__,
prefix=package.__name__+'.',
onerror=lambda x: None):
print(modname)
iter_modules répertorie uniquement les modules qui sont d'un niveau de profondeur. walk_packages obtient tous les submodules. Dans le cas de scipy, par exemple, walk_packages retourne
scipy.stats.stats
alors que iter_modules renvoie uniquement
scipy.stats
La documentation sur pkgutil (http://docs.python.org/library/pkgutil.html) ne pas la liste de toutes les fonctions intéressantes définis dans /usr/lib/python2.6/pkgutil.py.
Peut-être cela signifie que les fonctions ne font pas partie du "public" de l'interface et sont soumis à modification.
Cependant, à moins que de la version 2.6 de Python (et peut-être des versions antérieures?) pkgutil est livré avec un walk_packages méthode qui parcourt récursivement tous les les modules disponibles.
Voici une méthode qui, du haut de ma tête:
>>> import os
>>> filter(lambda i: type(i) == type(os), [getattr(os, j) for j in dir(os)])
[<module 'UserDict' from '/usr/lib/python2.5/UserDict.pyc'>, <module 'copy_reg' from '/usr/lib/python2.5/copy_reg.pyc'>, <module 'errno' (built-in)>, <module 'posixpath' from '/usr/lib/python2.5/posixpath.pyc'>, <module 'sys' (built-in)>]
Il pourrait certainement être nettoyé et améliorée.
EDIT: Voici une un peu plus sympa version:
>>> [m[1] for m in filter(lambda a: type(a[1]) == type(os), os.__dict__.items())]
[<module 'copy_reg' from '/usr/lib/python2.5/copy_reg.pyc'>, <module 'UserDict' from '/usr/lib/python2.5/UserDict.pyc'>, <module 'posixpath' from '/usr/lib/python2.5/posixpath.pyc'>, <module 'errno' (built-in)>, <module 'sys' (built-in)>]
>>> [m[0] for m in filter(lambda a: type(a[1]) == type(os), os.__dict__.items())]
['_copy_reg', 'UserDict', 'path', 'errno', 'sys']
REMARQUE: Cela permettra également de trouver des modules qui pourraient ne pas être nécessairement situé dans un sous-répertoire de l'emballage, si ils sont tiré dans son __init__.py
le fichier, donc, cela dépend de ce que tu veux dire par "une partie" d'un paquet.