Pregunta

¿Hay una manera fácil de encontrar todos los módulos que forman parte de un paquete python? He encontrado este viejo discusión, que en realidad no es concluyente, pero me gustaría tener una respuesta definitiva antes ruedo mi propia solución basada en os.listdir ().

¿Fue útil?

Solución

Sí, usted quiere algo basado en pkgutil o similar -. De esta manera se puede tratar por igual todos los paquetes sin tener en cuenta si se encuentran en los huevos o las cremalleras o así (donde os.listdir no ayudará)

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)

¿Cómo importar ellos también? Usted sólo puede usar __import__ de forma normal:

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

Otros consejos

La herramienta adecuada para este trabajo es pkgutil.walk_packages.

Para una lista de todos los módulos en su sistema:

import pkgutil
for importer, modname, ispkg in pkgutil.walk_packages(path=None, onerror=lambda x: None):
    print(modname)

Tenga en cuenta que walk_packages importa todos los sub-paquetes, pero no submódulos.

Si desea una lista de todos los submódulos de un paquete en concreto, puede utilizar algo como esto:

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 sólo lista los módulos que son de un nivel profundo. walk_packages se lleva todos los submódulos. En el caso de scipy, por ejemplo, walk_packages retornos

scipy.stats.stats

mientras iter_modules sólo se devuelve

scipy.stats

La documentación sobre pkgutil ( http://docs.python.org/library/pkgutil.html ) no enumera todas las funciones definidas en interesantes /usr/lib/python2.6/pkgutil.py.

Tal vez esto significa que las funciones no son parte de la interfaz "pública" y están sujetos a cambios.

Sin embargo, al menos como de Python 2.6 (y versiones tal vez antes?) pkgutil viene con un método walk_packages el que camina de forma recursiva a través de toda la módulos disponibles.

Esto funciona para mí:

import types

for key, obj in nltk.__dict__.iteritems():
    if type(obj) is types.ModuleType: 
        print key

He aquí una forma, la parte superior de mi cabeza:

>>> 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)>]

Sin duda, podría ser limpiado y mejorado.

EDIT: Aquí hay una versión un poco más bonitas:

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

Nota: Esto también encontrar módulos que podrían no necesariamente estar ubicados en un subdirectorio del paquete, si están tirados en __init__.py en su archivo, así que depende de lo que entendemos por " parte de" un paquete.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top