¿Cómo agregar un módulo de Python a syspath?

69

Tengo una estructura de archivo como esta:

Folder
   Common
      foo1.py
   TestFolder
      foo2.py

Quiero importar en foo2.py y foo1.py. Lo intenté pero no funciona en Ubuntu:

sys.path.append(os.path.abspath('../../'))
from Common import foo1.py
usuario284474
fuente
¿Tienes un __init__.pyarchivo en tu carpeta? así es como python crea paquetes y le permite importar módulos desde ese paquete. guide.python-distribute.org/creation.html
Bryan
Tengo el archivo init.py en Common y en TestFolder
user284474
lo necesita en el directorio de carpetas, así como en las subcarpetas si desea importar
Bryan
Este init .py está vacío?
user284474
1
Sí, puede estar vacío. A menos que necesite una determinada configuración para su paquete, pero debería estar bien con que esté vacío
Bryan

Respuestas:

115

Cómo Python encuentra sus módulos

Estrictamente tomado, un módulo es un solo archivo de Python, mientras que un paquete es una carpeta que contiene archivos de Python, acompañado de un archivo (puede estar vacío) llamado __init__.py, para decirle a Python que es un paquete desde el cual importar módulos. En ambos casos, los módulos necesitan su .pyextensión, pero la importación se realiza sin (ver más abajo).

Por defecto, Python busca sus módulos y paquetes en $PYTHONPATH.

Para averiguar qué se incluye en $ PYTHONPATH, ejecute el siguiente código en python (3):

import sys
print(sys.path)

Cómo agregar un directorio

De vez en cuando

Desde un archivo de Python, puede agregar rutas de acceso ocasionalmente a la ruta predeterminada agregando las siguientes líneas en la sección de encabezado de su aplicación o script de Python:

import sys
sys.path.insert(0, "/path/to/your/package_or_module")

Por ejemplo:

si tengo una carpeta: /home/myname/pythonfilesy quiero importar el archivo module_1.py, ubicado en ese directorio, lo agrego a la sección de encabezado de mi código:

import sys
sys.path.insert(0, "/home/myname/pythonfiles")

Y simplemente puedo importar el archivo module_1.py:

import module_1

Cuando creo un paquete y quiero importar módulos desde el paquete, necesito crear una carpeta que $PYTHONPATHcontenga los módulos, acompañada de un archivo (puede estar vacío) llamado__init__.py

Por ejemplo:

Para importar desde un paquete (carpeta) llamada my_packageen /home/myname/pythonfiles, añadir la /home/myname/pythonfilesruta a su $PYTHONPATH, al igual que en el ejemplo 1, e importar el módulo llamado module_2.py(dentro de la carpeta del paquete) simplemente con: `

from <packagename> import module_2

Agregar directorios a $PYTHONPATHpermanentemente:

Agregue la siguiente línea a su ~/.profilearchivo.

export PYTHONPATH=$PYTHONPATH:/path/you/want/to/add

Subdirectorios

Desde dentro de un paquete, los subdirectorios no se incluyen así; necesita "encadenar" los directorios. Para importar un módulo module_3.py, dentro de la carpeta subfolderdentro de la carpeta packagename:

import packagename.subfolder.module_3

Dado el hecho de que todas las subcarpetas en el paquete incluyen su propio __init__.pyarchivo.

Cuando un módulo está en el mismo directorio que el script o la aplicación

No es necesario insertar la ruta a un módulo cuando está en el mismo directorio que el script o la aplicación, se agrega automáticamente.

Ejemplo:

Si tengo una carpeta que contiene script.pyy module.py, simplemente puedo importar el módulo de la siguiente manera:

import module
Jacob Vlijm
fuente
También me gustaría sugerir leer python.org/dev/peps/pep-0328 , especialmente si está apuntando a Python 3 (o planea apuntar en el futuro)
zaadeh
¿Por qué printenv PYTHONPATHno hay nada?
Stevie G
1
sys.path.append("/path/to/your/package_or_module")También agrega una ruta al valor predeterminado y es menos confuso. En comparación con lo sys.path.insert(0,...)que tiene 0como primer argumento.
Paul Rougieux
1
@PaulRougieux: El problema con agregar a la ruta es que su módulo ya puede existir en otra parte de la ruta (en un archivo .egg, por ejemplo) y elegirá esa versión de su módulo en lugar de la que está en su archivo.
snark
6

La forma correcta de usar la importación relativa es:

from ..Common import foo1

Y también necesita un __init__.pyen todas sus carpetas.

Sylvain Pineau
fuente
1
Gracias. Pero si tengo un módulo que tiene dos carpetas, ¿cómo puedo importarlo? from .... La carpeta no funciona
usuario 284474
¿Funciona con un solo nivel?
Sylvain Pineau
Con un solo nivel funciona.
user284474
ok, ¿podrías por favor aceptar esta respuesta? para multinivel, aunque podría hacer una pregunta diferente, pero primero eche un vistazo a esta pregunta y esta respuesta para la mejor manera de llamar a sus módulos dentro de un paquete
Sylvain Pineau
¿Es esto cierto para Python 2 o Python 3? ¿O ambos?
alex
2

Nota: esta respuesta no está actualizada para la última versión de Python 3, pero está aquí para la versión anterior. Para obtener más información, lea los comentarios y https://www.python.org/dev/peps/pep-0420/


Esencialmente, cada carpeta con código python que desea agregar al syspath necesita un archivo __init__.py. Estos archivos __init__.py pueden estar vacíos.

don.joey
fuente
Según tengo entendido, este ya no es el caso, el directorio ahora se convierte en un "espacio de nombres".
Aaron Hall
@AaronHall interesante, fuente?
don.joey
1
Pruebe esto como prueba: python -c "from pathlib import Path; Path('ns').mkdir(); Path('ns/mod.py').write_text('''print('mod.py')'''); import ns.mod; from shutil import rmtree; rmtree('ns')"también aquí hay documentación relevante, PEP 420, que describe la adición de la semántica del paquete de espacio de nombres
Aaron Hall