proyectos ejemplos python python-3.x import module relative

python - ejemplos - django



Importación relativa en Python 3 no funciona (4)

Al iniciar un archivo de origen de python, está prohibido importar otro archivo, que está en el paquete actual, utilizando la importación relativa.

En la documentation se dice:

Tenga en cuenta que las importaciones relativas se basan en el nombre del módulo actual. Como el nombre del módulo principal siempre es "__main__", los módulos destinados a ser utilizados como el módulo principal de una aplicación Python siempre deben usar importaciones absolutas.

Entonces, como dijo , necesitas usar la importación absoluta en tal situación.

Tengo el siguiente directorio:

mydirectory ├── __init__.py ├── file1.py └── file2.py

Tengo una función f definida en file1.py.

Si, en file2.py, lo hago

from .file1 import f

Obtuve el siguiente error:

SystemError: módulo principal '''' no cargado, no puede realizar importación relativa

¿Por qué? ¿Y cómo hacerlo funcionar?


Lanzar módulos dentro de un paquete como ejecutables es una mala práctica .

Cuando desarrolla algo, o bien construye una biblioteca, que está destinada a ser importada por otros programas y, por lo tanto, no tiene mucho sentido permitir la ejecución de sus submódulos directamente, o crea un ejecutable en cuyo caso no hay razón para hacerlo parte de un paquete.

Esta es la razón por la que en setup.py distingue entre paquetes y scripts. Los paquetes se incluirán en paquetes de site-packages mientras que los scripts se instalarán en /usr/bin (o una ubicación similar según el sistema operativo).

Mi recomendación es utilizar el siguiente diseño:

/ ├── mydirectory | ├── __init__.py | ├── file1.py └── file2.py

Donde file2.py importa file1.py como cualquier otro código que quiera usar la biblioteca mydirectory , con una importación absoluta :

from mydirectory.file1 import f

Cuando escribe una setup.py comandos setup.py para el proyecto, simplemente enumera mydirectory como paquete y file2.py como una secuencia de comandos y todo funcionará. No es necesario sys.path con sys.path .

Si alguna vez, por alguna razón, realmente desea ejecutar un submódulo de un paquete, la forma correcta de hacerlo es usar el -m :

python -m mydirectory.file1

Esto carga todo el paquete y luego ejecuta el módulo como una secuencia de comandos, lo que permite que la importación relativa tenga éxito.

Yo personalmente evitaría hacer esto. También porque mucha gente ni siquiera sabe que puede hacer esto y terminará recibiendo el mismo error que usted y piensa que el paquete está roto.

Con respecto a la respuesta actualmente aceptada, que dice que solo debe usar una importación relativa implícita from file1 import f porque funcionará porque están en el mismo directorio:

¡Esto está mal !

  • No funcionará en python3, donde las importaciones relativas implícitas no se permiten y seguramente se romperán si tiene instalado un módulo file1 (¡ya que se importará en lugar de su módulo!).
  • Incluso si funciona, el file1 no se verá como parte del paquete mydirectory . Esto puede importar

    Por ejemplo, si file1 usa pickle , el nombre del paquete es importante para la correcta carga / descarga de datos.


ya que file1 y file2 están en el mismo directorio, ni siquiera necesita tener un archivo __init__.py . Si vas a escalar, entonces déjalo allí.

Para importar algo en un archivo en el mismo directorio, solo haz esto

from file1 import f

es decir, no necesita hacer la ruta relativa .file1 porque están en el mismo directorio.

Si su función principal, secuencia de comandos o lo que sea, que ejecutará toda la aplicación está en otro directorio, tendrá que hacer todo lo relacionado con el lugar donde se está ejecutando.


myproject/ mypackage ├── __init__.py ├── file1.py ├── file2.py └── file3.py mymainscript.py

Ejemplo para importar de un archivo a otro

#file1.py from myproject import file2 from myproject.file3 import MyClass

Importe el ejemplo del paquete al mainscript

#mymainscript.py import mypackage

https://docs.python.org/3/tutorial/modules.html#packages

https://docs.python.org/3/reference/import.html#regular-packages

https://docs.python.org/3/reference/simple_stmts.html#the-import-statement

https://docs.python.org/3/glossary.html#term-import-path

La variable sys.path es una lista de cadenas que determina la ruta de búsqueda del intérprete para los módulos. Se inicializa a una ruta predeterminada tomada de la variable de entorno PYTHONPATH o de un valor predeterminado incorporado si PYTHONPATH no está configurado. Puede modificarlo usando operaciones de lista estándar:

import sys sys.path.append(''/ufs/guido/lib/python'') sys.path.insert(0, ''/ufs/guido/myhaxxlib/python'')

Insertarlo al principio tiene el beneficio de garantizar que la ruta se busque antes que otras (incluso las integradas) en el caso de conflictos de nombres.