¿Podría alguien proporcionarme una buena manera de importar un directorio completo de módulos?
Tengo una estructura como esta:
/Foo
bar.py
spam.py
eggs.py
Traté de convertirlo en un paquete agregando __init__.pyy haciendo, from Foo import *pero no funcionó de la manera que esperaba.
python
python-import
Evan Fosmark
fuente
fuente

Respuestas:
Enumere todos los
.pyarchivos python ( ) en la carpeta actual y colóquelos como__all__variables en__init__.pyfuente
if not os.path.basename(f).startswith('_')o al menos,if not f.endswith('__init__.py')al final de la comprensión de la listaos.path.isfile(f)seaTrue. Eso filtraría enlaces simbólicos y directorios rotos comosomedir.py/(caso de esquina, lo admito, pero aún así ...)from . import *después de la configuración__all__si desea que los submódulos estén disponibles usando.(por ejemplomodule.submodule1, comomodule.submodule2, etc.).Agregue la
__all__variable a__init__.pycontener:Ver también http://docs.python.org/tutorial/modules.html
fuente
os.listdir()algo de filtrado, despojo de.pyextensión y__all__.moduleName.varNameref. stackoverflow.com/a/710603/248616Actualización en 2017: probablemente quieras usar
importliben su lugar.Haga que el directorio de Foo sea un paquete agregando un
__init__.py. En ese__init__.pycomplemento:Como lo desea dinámico (que puede o no ser una buena idea), enumere todos los archivos py con directorio dir e impórtelos con algo como esto:
Luego, desde su código, haga esto:
Ahora puede acceder a los módulos con
etc.
from Foo import *no es una buena idea por varias razones, incluidos los conflictos de nombres y la dificultad de analizar el código.fuente
__import__hackish, creo que sería mejor agregar los nombres__all__y luego ponerlosfrom . import *al final del guión__import__no es para usos generales, se usa porinterpreter, useimportlib.import_module()en su lugar.from . import eggsetc.__init__.pyantes de que Python pudiera importar. Con solamenteimport eggsconsigoModuleNotFoundError: No module named 'eggs'cuando se trata deimport Fooen elmain.pyen el directorio anterior.Ampliando la respuesta de Mihail, creo que la forma no hack (como no manejar las rutas de archivo directamente) es la siguiente:
__init__.pyarchivo vacío debajoFoo/Obtendrás:
fuente
RuntimeWarningmensajes también pueden ser evitados por no usar full_package_name en absoluto:importer.find_module(package_name).load_module(package_name).RuntimeWarningerrores también se pueden evitar (de una manera fea) importando el padre (nombre de directorio AKA). Una forma de hacerlo es -if dirname not in sys.modules: pkgutil.find_loader(dirname).load_module(dirname). Por supuesto, eso solo funciona sidirnamees una ruta relativa de un solo componente; sin cortes. Personalmente, prefiero el enfoque de @ Artfunkel de usar el nombre_paquete base en su lugar.Python, incluye todos los archivos en un directorio:
Para los novatos que simplemente no pueden hacer que funcione, que necesitan que lo agarren de la mano.
Cree una carpeta / home / el / foo y cree un archivo
main.pyen / home / el / foo. Coloque este código allí:Hacer un directorio
/home/el/foo/hellokittyHaga un archivo
__init__.pydebajo/home/el/foo/hellokittyy ponga este código allí:Hacer dos archivos de python:
spam.pyyham.pydebajo/home/el/foo/hellokittyDefina una función dentro de spam.py:
Defina una función dentro de ham.py:
Ejecutarlo:
fuente
import *se considera una mala práctica de codificación de Python. ¿Cómo haces esto sin eso?Me cansé de este problema yo mismo, así que escribí un paquete llamado automodinit para solucionarlo. Puede obtenerlo en http://pypi.python.org/pypi/automodinit/ .
El uso es así:
automodinitpaquete en sussetup.pydependencias.¡Eso es! A partir de ahora, la importación de un módulo establecerá __todos__ en una lista de archivos .py [co] en el módulo y también importará cada uno de esos archivos como si hubiera escrito:
Por lo tanto, el efecto de "from M import *" coincide exactamente con "import M".
automodinites feliz corriendo desde dentro de archivos ZIP y, por lo tanto, es seguro para ZIP.Niall
fuente
Sé que estoy actualizando una publicación bastante antigua, e intenté usarla
automodinit, pero descubrí que su proceso de configuración está roto para python3. Entonces, según la respuesta de Luca, se me ocurrió una respuesta más simple, que podría no funcionar con .zip, para este problema, así que pensé que debería compartirlo aquí:dentro del
__init__.pymódulo deyourpackage:y dentro de otro paquete a continuación
yourpackage:Luego tendrá todos los módulos que se colocan dentro del paquete cargado, y si escribe un nuevo módulo, también se importará automáticamente. Por supuesto, use ese tipo de cosas con cuidado, con grandes poderes conlleva grandes responsabilidades.
fuente
fuente
También me encontré con este problema y esta fue mi solución:
Esta función crea un archivo (en la carpeta proporcionada) llamado
__init__.py, que contiene una__all__variable que contiene cada módulo en la carpeta.Por ejemplo, tengo una carpeta llamada
Testque contiene:Entonces, en el script que quiero que se importen los módulos, escribiré:
Esto importará todo
Testy el__init__.pyarchivoTestahora contendrá:fuente
El ejemplo de Anurag con un par de correcciones:
fuente
¡Respuesta de Anurag Uniyal con mejoras sugeridas!
fuente
Ver que tu
__init__.pydefine__all__. Los módulos - paquetes doc dicefuente
Esta es la mejor manera que he encontrado hasta ahora:
fuente
Usar
importliblo único que tienes que agregar esfuente
error: Type of __all__ must be "Sequence[str]", not "List[Module]".__all__No es necesario definir siimport_modulese utiliza este enfoque basado.Mire el módulo pkgutil de la biblioteca estándar. Le permitirá hacer exactamente lo que quiera siempre que tenga un
__init__.pyarchivo en el directorio. El__init__.pyarchivo puede estar vacío.fuente
He creado un módulo para eso, que no se basa en
__init__.py(ni en ningún otro archivo auxiliar) y me hace escribir solo las siguientes dos líneas:Siéntase libre de reutilizar o contribuir: http://gitlab.com/aurelien-lourot/importdir
fuente
Simplemente impórtelos por importlib y agréguelos a
__all__(laaddacción es opcional) en forma recurrente en el__init__.pypaquete.fuente
pyCuando
from . import *no es lo suficientemente bueno, esta es una mejora sobre la respuesta de ted . Específicamente, el uso de__all__no es necesario con este enfoque.Tenga en cuenta que
module_name not in globals()está destinado a evitar volver a importar el módulo si ya está importado, ya que esto puede arriesgar las importaciones cíclicas.fuente