Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

670
Views
Cómo arreglar "Intento de importación relativa en un paquete que no sea" incluso con __init__.py

Estoy tratando de seguir PEP 328 , con la siguiente estructura de directorios:

 pkg/ __init__.py components/ core.py __init__.py tests/ core_test.py __init__.py

En core_test.py tengo la siguiente declaración de importación

 from ..components.core import GameLoopEvents

Sin embargo, cuando ejecuto, me sale el siguiente error:

 tests$ python core_test.py Traceback (most recent call last): File "core_test.py", line 3, in <module> from ..components.core import GameLoopEvents ValueError: Attempted relative import in non-package

Buscando encontré " la ruta relativa no funciona incluso con __init__.py " e " Importar un módulo desde una ruta relativa ", pero no ayudaron.

¿Hay algo que me estoy perdiendo aquí?

over 4 years ago · Santiago Trujillo
20 answers
Answer question

0

Esto es muy confuso, y si está usando IDE como pycharm, es un poco más confuso. Lo que funcionó para mí: 1. Realice la configuración del proyecto pycharm (si está ejecutando python desde un VE o desde el directorio de python) 2. No hay errores en la forma en que definió. en algún momento funciona con la clase de importación de carpeta1.archivo1

si no funciona, use import folder1.file1 3. Su variable de entorno debe mencionarse correctamente en el sistema o proporcionarla en su argumento de línea de comando.

over 4 years ago · Santiago Trujillo Report

0

Como ya ha marcado todo como un módulo, no hay necesidad de usar la referencia relativa si inicia como módulo de python.

En lugar de

 from ..components.core import GameLoopEvents

simplemente

 from pkg.components.core import GameLoopEvents

Cuando ejecute desde el padre de pkg, use lo siguiente

 python -m pkg.tests.core_test
over 4 years ago · Santiago Trujillo Report

0

Para mí, solo esto funcionó: tuve que establecer explícitamente el valor del paquete en el directorio principal y agregar el directorio principal a sys.path

 from os import path import sys if __package__ is None: sys.path.append( path.dirname( path.dirname( path.abspath(__file__) ) ) ) __package__= "myparent" from .subdir import something # the . can now be resolved

Ahora puedo ejecutar directamente mi script con python myscript.py .

over 4 years ago · Santiago Trujillo Report

0

python <main module>.py no funciona con importación relativa

El problema es que la importación relativa no funciona cuando ejecuta un módulo __main__ desde la línea de comando

 python <main_module>.py

Está claramente establecido en PEP 338 .

El lanzamiento de 2.5b1 mostró una interacción sorprendente (aunque obvia en retrospectiva) entre este PEP y PEP 328: las importaciones relativas explícitas no funcionan desde un módulo principal . Esto se debe al hecho de que las importaciones relativas se basan en __name__ para determinar la posición del módulo actual en la jerarquía del paquete. En un módulo principal, el valor de __name__ siempre es '__main__' , por lo que las importaciones relativas explícitas siempre fallarán (ya que solo funcionan para un módulo dentro de un paquete).

Porque

  • Python Bug Tracker Problema 1510172: ¿La importación absoluta/relativa no funciona?

En realidad, el problema no es exclusivo del modificador -m. El problema es que las importaciones relativas se basan en __name__ , y en el módulo principal, __name__ siempre tiene el valor __main__ . Por lo tanto, las importaciones relativas actualmente no pueden funcionar correctamente desde el módulo principal de una aplicación , porque el módulo principal no sabe dónde encaja realmente en el espacio de nombres del módulo de Python (esto es al menos reparable en teoría para los módulos principales ejecutados a través del -m modificador, pero los archivos ejecutados directamente y el intérprete interactivo no tienen suerte).

Para comprender mejor, consulte Importaciones relativas en Python 3 para obtener una explicación detallada y cómo superarlo.

over 4 years ago · Santiago Trujillo Report

0

Como dijo Paolo , tenemos 2 métodos de invocación:

 1) python -m tests.core_test 2) python tests/core_test.py

Una diferencia entre ellos es la cadena sys.path[0]. Dado que la interpretación buscará sys.path al importar , podemos hacerlo con tests/core_test.py :

 if __name__ == '__main__': import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from components import core <other stuff>

Y más después de esto, podemos ejecutar core_test.py con otros métodos:

 cd tests python core_test.py python -m core_test ...

Tenga en cuenta que solo se probó py36.

over 4 years ago · Santiago Trujillo Report

0

Este enfoque funcionó para mí y está menos desordenado que algunas soluciones:

 try: from ..components.core import GameLoopEvents except ValueError: from components.core import GameLoopEvents

El directorio principal está en mi PYTHONPATH y hay archivos __init__.py en el directorio principal y en este directorio.

Lo anterior siempre funcionó en python 2, pero python 3 a veces golpea un ImportError o ModuleNotFoundError (este último es nuevo en python 3.6 y una subclase de ImportError), por lo que el siguiente ajuste me funciona tanto en python 2 como en 3:

 try: from ..components.core import GameLoopEvents except ( ValueError, ImportError): from components.core import GameLoopEvents
over 4 years ago · Santiago Trujillo Report

0

El problema es con su método de prueba,

python core_test.py

entonces obtendrá este error ValueError: Intento de importación relativa en no paquete

Motivo: está probando su empaque desde una fuente que no es del paquete.

así que pruebe su módulo desde la fuente del paquete.

si esta es la estructura de su proyecto,

 pkg/ __init__.py components/ core.py __init__.py tests/ core_test.py __init__.py

paquete de cd

 python -m tests.core_test # dont use .py

o desde fuera paq/

 python -m pkg.tests.core_test

. si desea importar desde una carpeta en el mismo directorio. por cada paso atrás añade uno más.

 hi/ hello.py how.py

en how.py

 from .hi import hello

en caso de que quieras importar cómo desde hello.py

 from .. import how
over 4 years ago · Santiago Trujillo Report

0

Aquí hay una forma que cabreará a todos pero que funcionará bastante bien. En pruebas ejecutar:

 ln -s ../components components

Luego, importe los componentes como lo haría normalmente.

over 4 years ago · Santiago Trujillo Report

0

Debido a que su código contiene if __name__ == "__main__" , que no se importa como un paquete, será mejor que use sys.path.append() para resolver el problema.

over 4 years ago · Santiago Trujillo Report

0

Si. No lo estás usando como un paquete.

 python -m pkg.tests.core_test
over 4 years ago · Santiago Trujillo Report

0

Para profundizar en la respuesta de Ignacio Vázquez-Abrams :

El mecanismo de importación de Python funciona en relación con el __name__ del archivo actual. Cuando ejecuta un archivo directamente, no tiene su nombre habitual, sino que tiene "__main__" como nombre en su lugar. Así que las importaciones relativas no funcionan.

Puedes, como sugirió Igancio, ejecutarlo usando la opción -m . Si tiene una parte de su paquete que debe ejecutarse como un script, también puede usar el atributo __package__ para decirle a ese archivo qué nombre se supone que debe tener en la jerarquía del paquete.

Consulte http://www.python.org/dev/peps/pep-0366/ para obtener más detalles.

over 4 years ago · Santiago Trujillo Report

0

Depende de cómo desee iniciar su script.

Si desea iniciar su UnitTest desde la línea de comandos de forma clásica, es decir:

 python tests/core_test.py

Entonces, dado que en este caso los 'componentes' y las 'pruebas' son carpetas hermanas, puede importar el módulo relativo ya sea usando el método de inserción o el de adición del módulo sys.path . Algo como:

 import sys from os import path sys.path.append( path.dirname( path.dirname( path.abspath(__file__) ) ) ) from components.core import GameLoopEvents

De lo contrario, puede iniciar su secuencia de comandos con el argumento '-m' (tenga en cuenta que en este caso, estamos hablando de un paquete y, por lo tanto, no debe proporcionar la extensión '.py' ), es decir:

 python -m pkg.tests.core_test

En tal caso, simplemente puede usar la importación relativa como lo estaba haciendo:

 from ..components.core import GameLoopEvents

Finalmente, puede mezclar los dos enfoques, de modo que su secuencia de comandos funcione sin importar cómo se llame. Por ejemplo:

 if __name__ == '__main__': if __package__ is None: import sys from os import path sys.path.append( path.dirname( path.dirname( path.abspath(__file__) ) ) ) from components.core import GameLoopEvents else: from ..components.core import GameLoopEvents
over 4 years ago · Santiago Trujillo Report

0

Puede usar import components.core directamente si agrega el directorio actual a sys.path :

 if __name__ == '__main__' and __package__ is None: from os import sys, path sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))
over 4 years ago · Santiago Trujillo Report

0

Si su caso de uso es para ejecutar pruebas, y parece que lo es, entonces puede hacer lo siguiente. En lugar de ejecutar su script de prueba como python core_test.py use un marco de prueba como pytest . Luego, en la línea de comando, puede ingresar

 $$ py.test

Eso ejecutará las pruebas en su directorio. Esto soluciona el problema de que __name__ es __main__ que fue señalado por @BrenBarn. Luego, coloque un archivo __init__.py vacío en su directorio de prueba, esto hará que el directorio de prueba sea parte de su paquete. Entonces serás capaz de hacer

 from ..components.core import GameLoopEvents

Sin embargo, si ejecuta su script de prueba como un programa principal, las cosas fallarán una vez más. Así que solo usa el corredor de prueba. Tal vez esto también funcione con otros corredores de prueba, como nosetests , pero no lo he comprobado. Espero que esto ayude.

over 4 years ago · Santiago Trujillo Report

0

Mi solución rápida es agregar el directorio a la ruta:

 import sys sys.path.insert(0, '../components/')
over 4 years ago · Santiago Trujillo Report

0

En core_test.py, haga lo siguiente:

 import sys sys.path.append('../components') from core import GameLoopEvents
over 4 years ago · Santiago Trujillo Report

0

Si alguien está buscando una solución alternativa, me topé con una. Aquí hay un poco de contexto. Quería probar uno de los métodos que tengo en un archivo. Cuando lo ejecuto desde adentro

 if __name__ == "__main__":

siempre se quejó de las importaciones relativas. Traté de aplicar las soluciones anteriores, pero no funcionó, ya que había muchos archivos anidados, cada uno con múltiples importaciones.

Esto es lo que hice. Acabo de crear un lanzador, un programa externo que importaría los métodos necesarios y los llamaría. Aunque, no es una gran solución, funciona.

over 4 years ago · Santiago Trujillo Report

0

Viejo hilo. Descubrí que agregar un __all__= ['submodule', ...] al archivo __init__.py y luego usar from <CURRENT_MODULE> import * en el objetivo funciona bien.

over 4 years ago · Santiago Trujillo Report

0

Puede usar from pkg.components.core import GameLoopEvents , por ejemplo, uso pycharm, la siguiente es la imagen de la estructura de mi proyecto, solo importo desde el paquete raíz, luego funciona:

ingrese la descripción de la imagen aquí

over 4 years ago · Santiago Trujillo Report

0

Prueba esto

 import components from components import *
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!