sirve que para paquetes otro modulos llamar librería importar funcion from entre diferencia como comando clases archivo python jupyter-notebook relative-import

para - paquetes de python



importar la función local desde un módulo alojado en otro directorio con importaciones relativas en el cuaderno jupyter usando python3 (3)

Tengo una estructura de directorio similar a la siguiente

meta_project project1 __init__.py lib module.py __init__.py notebook_folder notebook.jpynb

Cuando trabajo en notebook.jpynb si intento usar una importación relativa para acceder a una función de function() en module.py con:

from ..project1.lib.module import function

Obtuve el siguiente error

SystemError Traceback (most recent call last) <ipython-input-7-6393744d93ab> in <module>() ----> 1 from ..project1.lib.module import function SystemError: Parent module '''' not loaded, cannot perform relative import

¿Hay alguna manera de hacer que esto funcione utilizando importaciones relativas?

Tenga en cuenta que el servidor de notebook se instancia en el nivel del directorio meta_project , por lo que debe tener acceso a la información en esos archivos.

Tenga en cuenta, además, que al menos como el proyecto original project1 no se pensó como un módulo y, por lo tanto, no tiene un archivo __init__.py , solo se entiende como un directorio del sistema de archivos. Si la solución al problema requiere tratarlo como un módulo e incluir un archivo __init__.py (incluso uno en blanco) está bien, pero hacerlo no es suficiente para resolver el problema.

Comparto este directorio entre máquinas y las importaciones relativas me permiten usar el mismo código en todas partes, y a menudo uso portátiles para la creación rápida de prototipos, por lo que es poco probable que las sugerencias que implican hackear rutas absolutas sean útiles.

Editar: Esto es diferente a las importaciones relativas en Python 3 , que habla sobre las importaciones relativas en Python 3 en general y, en particular, la ejecución de un script desde un directorio de paquetes. Esto tiene que ver con trabajar en un cuaderno jupyter tratando de llamar a una función en un módulo local en otro directorio que tiene aspectos generales y particulares diferentes.


Hasta ahora, la respuesta aceptada ha funcionado mejor para mí. Sin embargo, mi preocupación siempre ha sido que existe un escenario probable en el que podría refactorizar el directorio de notebooks en subdirectorios, lo que requiere cambiar el module_path en cada cuaderno. Decidí agregar un archivo python dentro de cada directorio de notebook para importar los módulos requeridos.

Por lo tanto, teniendo la siguiente estructura de proyecto:

project |__notebooks |__explore |__ notebook1.ipynb |__ notebook2.ipynb |__ project_path.py |__ explain |__notebook1.ipynb |__project_path.py |__lib |__ __init__.py |__ module.py

project_path.py el archivo project_path.py en cada subdirectorio del notebooks/explore ( notebooks/explore y notebooks/explain ). Este archivo contiene el código para las importaciones relativas (de @metakermit):

import sys import os module_path = os.path.abspath(os.path.join(os.pardir, os.pardir)) if module_path not in sys.path: sys.path.append(module_path)

De esta manera, solo necesito hacer importaciones relativas dentro del archivo project_path.py , y no en los cuadernos. Los archivos de los cuadernos solo tendrían que importar project_path antes de importar lib . Por ejemplo en 0.0-notebook.ipynb :

import project_path import lib

La advertencia aquí es que revertir las importaciones no funcionaría. ESTO NO FUNCIONA:

import lib import project_path

Por lo tanto, se debe tener cuidado durante las importaciones.


Tuve casi el mismo ejemplo que usted en este cuaderno donde quería ilustrar el uso de la función de un módulo adyacente de manera SECA.

Mi solución fue informarle a Python de esa ruta de importación de módulo adicional agregando un fragmento como este al cuaderno:

import os import sys module_path = os.path.abspath(os.path.join(''..'')) if module_path not in sys.path: sys.path.append(module_path)

Esto le permite importar la función deseada desde la jerarquía del módulo:

from project1.lib.module import function # use the function normally function(...)

Tenga en cuenta que es necesario agregar archivos __init__.py vacíos a __init__.py carpetas project1 / y lib / si aún no los tiene.


Vine aquí buscando las mejores prácticas para abstraer código a submódulos cuando trabajaba en Notebooks. No estoy seguro de que haya una mejor práctica. He estado proponiendo esto.

Una jerarquía de proyecto como tal:

├── ipynb │   ├── 20170609-Examine_Database_Requirements.ipynb │   └── 20170609-Initial_Database_Connection.ipynb └── lib ├── __init__.py └── postgres.py

Y desde 20170609-Initial_Database_Connection.ipynb :

In [1]: cd .. In [2]: from lib.postgres import database_connection

Esto funciona porque, de manera predeterminada, Jupyter Notebook puede analizar el comando cd . Tenga en cuenta que esto no hace uso de la magia de Python Notebook. Simplemente funciona sin anteponer %bash .

Considerando que 99 de cada 100 veces estoy trabajando en Docker usando una de las imágenes del Proyecto Jupyter Docker , la siguiente modificación es idempotente

In [1]: cd /home/jovyan In [2]: from lib.postgres import database_connection