Liste de tous les modules qui font partie d'un paquet python?

Est-il un moyen simple pour trouver tous les modules qui font partie d'un paquet python? J'ai trouvé cette vieille discussion , qui n'est pas vraiment concluante, mais j'aimerais avoir une réponse définitive avant de déployer ma propre solution basée sur os.listdir ().

75
demandé sur CharlesB 2009-11-10 15:47:30

4 réponses

Oui, vous voulez quelque chose basé sur pkgutil ou similaire -- de cette façon, vous pouvez traiter tous les paquets de la même façon, peu importe s'ils sont dans des oeufs ou des fermetures à glissière ou ainsi (où os.listdir n'aidera pas).

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
114
répondu u0b34a0f6ae 2009-11-10 13:41:16

l'outil idéal pour ce travail est pkgutil.walk_packages.

pour lister 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 importe tous les sous-paquets, mais pas les sous-modules.

si vous souhaitez lister tous les sous-modules 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 liste seulement les modules qui sont à un niveau de profondeur. walk_packages obtient tout les submodules. Dans le cas de scipy, par exemple, walk_packages retourne

scipy.stats.stats

alors que iter_modules retourne seulement

scipy.stats

la documentation sur pkgutil ( http://docs.python.org/library/pkgutil.html ) ne Liste pas toutes les fonctions intéressantes définies dans /usr/lib/python2.6/pkgutil.py.

peut-être cela signifie que les fonctions ne font pas partie de l'interface "publique" et sont soumises à changement.

cependant, au moins à partir de Python 2.6 (et peut-être des versions antérieures?) pkgutil est livré avec une méthode walk_packages qui parcourt récursivement tous les les modules disponibles.

34
répondu unutbu 2009-11-10 15:15:48

ça marche pour moi:

import types

for key, obj in nltk.__dict__.iteritems():
    if type(obj) is types.ModuleType: 
        print key
3
répondu DarinP 2014-03-04 11:14:47

voici un chemin, 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)>]

elle pourrait certainement être nettoyée et améliorée.

EDIT: Ici est un peu une version plus sympathique:

>>> [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']

NOTE: cela permettra également de trouver des modules qui ne se trouvent pas nécessairement dans un sous-répertoire du paquet, s'ils sont tirés dans son fichier __init__.py , donc cela dépend de ce que vous entendez par " partie "un paquet.

-2
répondu Steve Losh 2009-11-10 13:07:45