¿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__.py
y haciendo, from Foo import *
pero no funcionó de la manera que esperaba.
python
python-import
Evan Fosmark
fuente
fuente
Respuestas:
Enumere todos los
.py
archivos python ( ) en la carpeta actual y colóquelos como__all__
variables en__init__.py
fuente
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__.py
contener:Ver también http://docs.python.org/tutorial/modules.html
fuente
os.listdir()
algo de filtrado, despojo de.py
extensión y__all__
.moduleName.varName
ref. stackoverflow.com/a/710603/248616Actualización en 2017: probablemente quieras usar
importlib
en su lugar.Haga que el directorio de Foo sea un paquete agregando un
__init__.py
. En ese__init__.py
complemento: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 eggs
etc.__init__.py
antes de que Python pudiera importar. Con solamenteimport eggs
consigoModuleNotFoundError: No module named 'eggs'
cuando se trata deimport Foo
en elmain.py
en 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__.py
archivo vacío debajoFoo/
Obtendrás:
fuente
RuntimeWarning
mensajes también pueden ser evitados por no usar full_package_name en absoluto:importer.find_module(package_name).load_module(package_name)
.RuntimeWarning
errores 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 sidirname
es 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.py
en / home / el / foo. Coloque este código allí:Hacer un directorio
/home/el/foo/hellokitty
Haga un archivo
__init__.py
debajo/home/el/foo/hellokitty
y ponga este código allí:Hacer dos archivos de python:
spam.py
yham.py
debajo/home/el/foo/hellokitty
Defina 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í:
automodinit
paquete en sussetup.py
dependencias.¡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".
automodinit
es 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__.py
mó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
Test
que contiene:Entonces, en el script que quiero que se importen los módulos, escribiré:
Esto importará todo
Test
y el__init__.py
archivoTest
ahora contendrá:fuente
El ejemplo de Anurag con un par de correcciones:
fuente
¡Respuesta de Anurag Uniyal con mejoras sugeridas!
fuente
Ver que tu
__init__.py
define__all__
. Los módulos - paquetes doc dicefuente
Esta es la mejor manera que he encontrado hasta ahora:
fuente
Usar
importlib
lo único que tienes que agregar esfuente
error: Type of __all__ must be "Sequence[str]", not "List[Module]"
.__all__
No es necesario definir siimport_module
se 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__.py
archivo en el directorio. El__init__.py
archivo 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__
(laadd
acción es opcional) en forma recurrente en el__init__.py
paquete.fuente
py
Cuando
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