programacion módulo modulos lista librerias instalar importa descargar cuando contenido basicas python module package

modulos - ¿Existe una forma estándar de enumerar los nombres de los módulos de Python en un paquete?



modulos python 3 (8)

¿Existe una manera directa de listar los nombres de todos los módulos en un paquete, sin usar __all__ ?

Por ejemplo, dado este paquete:

/testpkg /testpkg/__init__.py /testpkg/modulea.py /testpkg/moduleb.py

Me pregunto si hay una forma estándar o incorporada de hacer algo como esto:

>>> package_contents("testpkg") [''modulea'', ''moduleb'']

El enfoque manual sería iterar a través de las rutas de búsqueda del módulo para encontrar el directorio del paquete. Uno podría enumerar todos los archivos en ese directorio, filtrar los archivos de nombre único py / pyc / pyo, quitar las extensiones y devolver esa lista. Pero esto parece una buena cantidad de trabajo para algo que el mecanismo de importación de módulos ya está haciendo internamente. ¿Esa funcionalidad está expuesta en cualquier lugar?


Basado en el ejemplo de cdleary, aquí hay una ruta de listado de versiones recursivas para todos los submódulos:

import imp, os def iter_submodules(package): file, pathname, description = imp.find_module(''isc_datasources'') for dirpath, _, filenames in os.walk(pathname): for filename in filenames: if os.path.splitext(filename)[1] == ".py": yield os.path.join(dirpath, filename)


Esta es una versión recursiva que funciona con python 3.6 y superior:

import importlib.util from pathlib import Path import os MODULE_EXTENSIONS = ''.py'' def package_contents(package_name): spec = importlib.util.find_spec(package_name) if spec is None: return set() pathname = Path(spec.origin).parent ret = set() with os.scandir(pathname) as entries: for entry in entries: if entry.name.startswith(''__''): continue current = ''.''.join((package_name, entry.name.partition(''.'')[0])) if entry.is_file(): if entry.name.endswith(MODULE_EXTENSIONS): ret.add(current) elif entry.is_dir(): ret.add(current) ret |= package_contents(current) return ret


Tal vez esto hará lo que estás buscando?

import imp import os MODULE_EXTENSIONS = (''.py'', ''.pyc'', ''.pyo'') def package_contents(package_name): file, pathname, description = imp.find_module(package_name) if file: raise ImportError(''Not a package: %r'', package_name) # Use a set because some may be both source and compiled. return set([os.path.splitext(module)[0] for module in os.listdir(pathname) if module.endswith(MODULE_EXTENSIONS)])


Usando python2.3 y superior , también puedes usar el módulo pkgutil :

>>> import pkgutil >>> [name for _, name, _ in pkgutil.iter_modules([''testpkg''])] [''modulea'', ''moduleb'']

EDITAR: tenga en cuenta que el parámetro no es una lista de módulos, sino una lista de rutas, por lo que es posible que desee hacer algo como esto:

>>> import os.path, pkgutil >>> import testpkg >>> pkgpath = os.path.dirname(testpkg.__file__) >>> print [name for _, name, _ in pkgutil.iter_modules([pkgpath])]


imprimir dir (módulo)


No sé si estoy pasando por alto algo, o si las respuestas son obsoletas pero;

Según lo declarado por el usuario815423426, esto solo funciona para objetos en vivo y los módulos enumerados son solo módulos que se importaron anteriormente.

Listado de módulos en un paquete parece muy fácil de usar inspect :

>>> import inspect, testpkg >>> inspect.getmembers(testpkg, inspect.ismodule) [''modulea'', ''moduleb'']


def package_contents(package_name): package = __import__(package_name) return [module_name for module_name in dir(package) if not module_name.startswith("__")]


import module help(module)