es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo importar correctamente un paquete vecino en el paquete actual en Python?

Sé que hay un millón de preguntas y artículos similares que describen cómo definir y gestionar paquetes en general, pero lo siguiente no parece funcionar y se me han acabado las cosas que intentar. Espero que esté pasando por alto algo completamente obvio para otra persona.

Esta es mi estructura de proyecto actual:

root-folder/
  |- app/
      |- cube/
          |- algorithms/
              |- __init__.py
              |- utils.py
              |- ...
          |- models/
              |- __init__.py
              |- cube.py
              |- ...
          |- __init__.py
          |- main.py
          |- README.md
      |- presentation/
          |- cli_test/
              |- __init__.py
              |- run.py
          |- unity/
              |- __init__.py
              |- producer.py
          |- __init__.py
          |- README.md
      |- __init__.py

Estoy intentando importar una función de main.py en app.cube dentro de producer.py en app.presentation.unity de la siguiente manera:

from app.cube.main import run

pero cuando intento ejecutar el archivo del productor, me da lo siguiente:

$ python app/presentation/unity/producer.py
Traceback (most recent call last):
  File "app/presentation/unity/producer.py", line 3, in <module>
    from app.cube.main import run
ModuleNotFoundError: No module named 'app'

He intentado mover archivos, cambiar nombres de carpetas, agregar y eliminar archivos __init__.py, pero siempre obtengo un problema similar. En la configuración actual, todos los archivos __init__.py están vacíos, por cierto.

Otra cosa a tener en cuenta es que la carpeta cube solía estar en el nivel raíz del proyecto antes de que agregara la carpeta presentation, y podía importar funciones y clases en ambos sentidos entre los módulos models y algorithms, e importar cosas del módulo cube al nivel raíz. El contenido de la carpeta cube no ha cambiado desde entonces. Es como si agregar una capa adicional no funcionara o algo así, lo cual suena tonto.

Para obtener información final, estoy utilizando Python 3.8.5 instalado a través de pyenv 2.2.0 en MacOs Catalina (10.15.6)


¡Solución!

Como se propuso en el primer comentario de esta publicación, al ejecutarlo de la siguiente manera, puedes ejecutar un “módulo de biblioteca como un script” ¡y ahora funciona para mí!
python -m app.presentation.unity.producer

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El problema aquí parece estar en la forma en que estás intentando importar la función run desde main.py. En lugar de usar una importación relativa, estás intentando importarla usando una importación absoluta empezando desde el directorio raíz. Esto está causando el error ModuleNotFoundError ya que el directorio raíz no está definido como un módulo en tu entorno de Python.

    Para solucionar esto, puedes usar una importación relativa desde producer.py para importar la función run. Suponiendo que tanto main.py como producer.py están en el mismo paquete unity, puedes modificar tu declaración de importación de la siguiente manera:

    from ...cube.main import run
    

    Aquí, los ... en la declaración de importación representan subir tres niveles en la jerarquía del paquete para llegar al paquete app, luego bajar al paquete cube y finalmente al módulo main.

    Como alternativa, también puedes ejecutar el archivo producer.py usando la opción -m junto con la ruta completa al archivo del módulo. Esto te permitirá ejecutar un “módulo de librería como un script”, añadiendo efectivamente el directorio raíz a la ruta de Python. Puedes hacer esto de la siguiente manera:

    python -m app.presentation.unity.producer
    

    Esto debería resolver el error ModuleNotFoundError y permitirte importar la función run desde main.py.

Comments are closed.