Tengo la siguiente estructura de carpetas.
application/app/folder/file.py
y quiero importar algunas funciones de file.py en otro archivo de Python que reside en
application/app2/some_folder/some_file.py
He intentado
from application.app.folder.file import func_name
y algunos otros intentos, pero hasta ahora no pude importar correctamente. ¿Cómo puedo hacer esto?
Respuestas:
Por defecto, no puedes. Al importar un archivo, Python solo busca en el directorio actual, el directorio desde el que se ejecuta el script de punto de entrada y
sys.path
que incluye ubicaciones como el directorio de instalación del paquete (en realidad es un poco más complejo que esto, pero esto cubre la mayoría de los casos) .Sin embargo, puede agregar a la ruta de Python en tiempo de ejecución:
fuente
sys.path.append('/path/to/application/app/folder')
está más limpio imosys.path
devuelve unalist
, no unadeque
, y sería tonto para convertir lalist
a unadeque
ida y vuelta.No hay nada malo con:
Solo asegúrese de que
folder
también contenga un__init__.py
, esto permite que se incluya como un paquete. No estoy seguro de por qué hablan las otras respuestasPYTHONPATH
.fuente
PYTHONPATH
es necesario modificar . Digamos que tiene dos carpetas en el mismo nivel:A
yB
.A
tiene un__init.py__
. Intenta importar algo desdeB
dentroA
.init.py
o__init__.py
?application
yaapp
son paquetes (es decir, que ya tiene__init__.py
en ambos). Como resultado de agregar__init__.py
también afolder
, seapplication.app.folder
convierte en un (sub) paquete , desde el cual puede acceder al móduloapplication.app.folder.file
, cuyo símbolofunc_name
ahora se puede importarCuando los módulos están en ubicaciones paralelas, como en la pregunta:
Esta taquigrafía hace que un módulo sea visible para el otro:
fuente
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
cli/foo.py
desde la línea de comando pudieseimport cli.bar
sys.path.append('.')
importar el módulo utilizandofrom app2.some_folder.some_file import your_function
. Alternativamente, lo que funciona para mí se ejecutapython3 -m app2.another_folder.another_file
desde la carpeta raíz.Primero importe sys en name-file.py
En segundo lugar, agregue la ruta de la carpeta en name-file.py
Tercero Cree un archivo en blanco llamado __ init __.py en su subdirectorio (esto le dice a Python que es un paquete)
Cuarto, importe el módulo dentro de la carpeta en name-file.py
fuente
sys.path.insert
comando. Como tal, la respuesta deja la pregunta, si esta solución funciona incluso cuando la carpeta de nombres se encuentra en una ubicación arbitraria.Creo que una forma ad-hoc sería utilizar la variable de entorno
PYTHONPATH
como se describe en la documentación: Python2 , Python3fuente
Las respuestas aquí carecen de claridad, esto se prueba en Python 3.6
Con esta estructura de carpetas:
Donde
myfile.py
tiene el contenido:La declaración de importación en
main.py
es:y esto imprimirá hola .
fuente
__init__.py
?__init__.py
no funciona para mí. Estoy usando Py 3.6.5 en Ubuntu 18. Funciona en Pycharm pero no desde la terminalSu problema es que Python busca en el directorio de Python este archivo y no lo encuentra. Debe especificar que está hablando sobre el directorio en el que se encuentra y no sobre el de Python.
Para hacer esto, cambia esto:
from application.app.folder.file import func_name
a esto:
Al agregar el punto que está diciendo, busque en esta carpeta la carpeta de la aplicación en lugar de buscar en el directorio de Python.
fuente
Por lo que sé, agregar un
__init__.py
archivo directamente en la carpeta de las funciones que desea importar hará el trabajo.fuente
sys.path.append(tools_dir)
en Windows y no necesito añadir un__init__.py' file in my directory
tools_dir`En Python 3.4 y versiones posteriores, puede importar directamente desde un archivo fuente (enlace a la documentación) . Esta no es la solución más simple, pero incluyo esta respuesta para completar.
Aquí hay un ejemplo. Primero, el archivo a importar, llamado
foo.py
:El código que importa el archivo anterior, inspirado en gran medida por el ejemplo en la documentación:
La salida:
Tenga en cuenta que el nombre de la variable, el nombre del módulo y el nombre del archivo no necesitan coincidir. Este código aún funciona:
La salida:
La importación programática de módulos se introdujo en Python 3.1 y le brinda más control sobre cómo se importan los módulos. Consulte la documentación para más información.
fuente
Trabajó para mí en python3 en linux
fuente
sys.path.append("/home/linux/folder/")
- Asegúrese de no utilizar un acceso directo, por ejemplo"~/folder/"
Pruebe las importaciones relativas de Python:
Cada punto inicial es otro nivel superior en la jerarquía que comienza con el directorio actual.
¿Problemas? Si esto no funciona para usted, entonces probablemente le estén molestando las numerosas importaciones relativas de gotcha. Lea las respuestas y los comentarios para obtener más detalles: Cómo corregir "Intento de importación relativa en un paquete" incluso con __init__.py
Sugerencia: tener
__init__.py
en cada nivel de directorio. Es posible que necesitepython -m application.app2.some_folder.some_file
(dejando .py) que ejecuta desde el directorio de nivel superior o que tenga ese directorio de nivel superior en su PYTHONPATH. ¡Uf!fuente
Me enfrenté al mismo desafío, especialmente al importar varios archivos, así es como logré superarlo.
fuente
Teniendo en cuenta
application
que el directorio raíz para su proyecto pitón, crear un vacío__init__.py
archivo enapplication
,app
yfolder
carpetas. Luego, en susome_file.py
hacer cambios de la siguiente manera para obtener la definición de func_name:fuente
Usar sys.path.append con una ruta absoluta no es ideal cuando se mueve la aplicación a otros entornos. Usar una ruta relativa no siempre funcionará porque el directorio de trabajo actual depende de cómo se invocó el script.
Como la estructura de carpetas de la aplicación es fija, podemos usar os.path para obtener la ruta completa del módulo que deseamos importar. Por ejemplo, si esta es la estructura:
Y digamos que desea importar el módulo "mango". Puede hacer lo siguiente en vanilla.py:
Por supuesto, no necesita la variable mango_dir.
Para entender cómo funciona esto, mira este ejemplo de sesión interactiva:
Y revise la documentación de os.path .
fuente
Esto funciona para mí en windows
fuente
Soy bastante especial: ¡uso Python con Windows!
Acabo de completar la información: tanto para Windows como para Linux, tanto la ruta relativa como la absoluta funcionan
sys.path
(necesito rutas relativas porque uso mis scripts en varias PC y en diferentes directorios principales).Y cuando se usa Windows tanto
\
y/
se puede usar como separador para los nombres de archivo y, por supuesto, debe duplicarse\
en cadenas de Python,algunos ejemplos válidos:
(nota: creo que
/
es más conveniente que un\
evento si es menos 'nativo de Windows' porque es compatible con Linux y más simple de escribir y copiar en el explorador de Windows)fuente
Si el propósito de cargar un módulo desde una ruta específica es ayudarlo durante el desarrollo de un módulo personalizado, puede crear un enlace simbólico en la misma carpeta del script de prueba que apunte a la raíz del módulo personalizado. La referencia de este módulo tendrá prioridad sobre cualquier otro módulo instalado con el mismo nombre para cualquier script ejecutado en esa carpeta.
Probé esto en Linux pero debería funcionar en cualquier sistema operativo moderno que admita enlaces simbólicos.
Una ventaja de este enfoque es que puede señalar un módulo que se encuentra en su propia copia de trabajo de la rama SVC local, lo que puede simplificar en gran medida el tiempo del ciclo de desarrollo y reducir los modos de falla de la gestión de diferentes versiones del módulo.
fuente
En mi caso tenía una clase para importar. Mi archivo se veía así:
En mi archivo principal incluí el código a través de:
fuente
Me encontré con la misma pregunta varias veces, así que me gustaría compartir mi solución.
Versión de Python: 3.X
La siguiente solución es para alguien que desarrolla su aplicación en Python versión 3.X porque Python 2 no es compatible desde el 1 de enero de 2020 .
Estructura del proyecto
En python 3, no necesita
__init__.py
en el subdirectorio de su proyecto debido a los Paquetes de espacio de nombres implícitos . Ver ¿ No se requiere init .py para los paquetes en Python 3.3+?Planteamiento del problema
En
file_b.py
, me gustaría importar una claseA
enfile_a.py
la carpeta a.Soluciones
# 1 Una manera rápida pero sucia
Sin instalar el paquete como si actualmente estuviera desarrollando un nuevo proyecto
Usando
try catch
para comprobar si los errores. Ejemplo de código:# 2 Instala tu paquete
Una vez que instaló su aplicación (en esta publicación, el tutorial de instalación no está incluido)
Puedes simplemente
¡Feliz codificación!
fuente
Estaba trabajando en un proyecto
a
que quería que los usuarios instalaranpip install a
con la siguiente lista de archivos:setup.py
MANIFEST.in
a / init .py
a / a.py
a / b / init .py
a / b / b.py
Instalé el módulo ejecutando lo siguiente desde el directorio con
MANIFEST.in
:Entonces, desde una ubicación totalmente diferente en mi sistema de archivos
/moustache/armwrestle
pude ejecutar:Lo que confirmó que
a.cats
efectivamente era igual a 0 y dea.b.dogs
hecho igual a 1, según lo previsto.fuente
En lugar de solo hacer un
import ...
, haz esto:from <MySubFolder> import <MyFile>
MyFile está dentro del MySubFolder.
fuente
Puede actualizar el shell de Python presionando f5, o vaya a Ejecutar-> Ejecutar módulo. De esta manera, no tiene que cambiar el directorio para leer algo del archivo. Python cambiará automáticamente el directorio. Pero si desea trabajar con diferentes archivos de diferentes directorios en Python Shell, puede cambiar el directorio en sys, como dijo Cameron anteriormente.
fuente
Así que hice clic derecho en mi IDE, agregué uno nuevo
folder
y me preguntaba por qué no podía importarlo. Más tarde me di cuenta de que tenía que hacer clic derecho y crear un paquete de Python, y no una carpeta clásica del sistema de archivos. O bien, un método post mortem está agregando un__init__.py
(lo que hace que Python trate la carpeta del sistema de archivos como un paquete) como se menciona en otras respuestas. Agregue esta respuesta aquí en caso de que alguien haya tomado esta ruta.fuente
Puede usar importlib para importar módulos donde desea importar un módulo desde una carpeta usando una cadena de esta manera:
Este ejemplo tiene un main.py que es el código anterior, luego una carpeta llamada Scripts y luego puede llamar a lo que necesite de esta carpeta cambiando la
scriptName
variable. Luego puede usarscript
para hacer referencia a este módulo. como si tuviera una función llamadaHello()
en el módulo Snake, puede ejecutar esta función al hacerlo:He probado esto en Python 3.6
fuente
He tenido estos problemas varias veces. He venido mucho a esta misma página. En mi último problema tuve que ejecutarlo
server
desde un directorio fijo, pero cada vez que depuraba quería ejecutarlo desde diferentes subdirectorios.hicieron NO trabajo para mí porque en diferentes módulos tuve que leer diferentes * .csv archivos que estaban todos en el mismo directorio.
Al final, lo que funcionó para mí no fue pitónico, supongo, pero:
Utilicé un
if __main__
encima del módulo que quería depurar , que se ejecuta desde una ruta diferente a la habitual.Entonces:
fuente