import local function from a module housed in another directory with relative imports in jupyter notebook using python3
我有一个类似于以下的目录结构
1 2 3 4 5 6 7 8 | meta_project project1 __init__.py lib module.py __init__.py notebook_folder notebook.jpynb |
在
1 | from ..project1.lib.module import function |
我收到以下错误
1 2 3 4 5 | 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 |
有没有办法让这个使用相对导入工作?
请注意,笔记本服务器在
另请注意,至少与最初预期的
我在机器和相对导入之间共享这个目录允许我在任何地方使用相同的代码,&amp;我经常使用笔记本进行快速原型设计,所以涉及黑客攻击绝对路径的建议不太可能有用。
编辑:这与Python 3中的相对导入不同,Python 3通常讨论Python 3中的相对导入,特别是从包目录中运行脚本。这与在jupyter笔记本中工作有关,试图在另一个目录中的本地模块中调用一个函数,该目录具有不同的一般和特定方面。
我在这个笔记本中有几乎和你一样的例子,我想以干燥的方式说明相邻模块功能的用法。
我的解决方案是通过向笔记本添加像这样的代码片段来告诉Python其他模块导入路径:
1 2 3 4 5 | import os import sys module_path = os.path.abspath(os.path.join('..')) if module_path not in sys.path: sys.path.append(module_path) |
这允许您从模块层次结构导入所需的功能:
1 2 3 | from project1.lib.module import function # use the function normally function(...) |
请注意,如果您还没有将空
来到这里寻找在笔记本中工作时将代码抽象到子模块的最佳实践。我不确定是否有最好的做法。我一直在提议这个。
项目层次结构如下:
1 2 3 4 5 6 | ├── ipynb │ ├── 20170609-Examine_Database_Requirements.ipynb │ └── 20170609-Initial_Database_Connection.ipynb └── lib ├── __init__.py └── postgres.py |
从
1 2 3 | In [1]: cd .. In [2]: from lib.postgres import database_connection |
这是有效的,因为默认情况下,Jupyter Notebook可以解析
考虑到我使用Project Jupyter Docker图像之一在Docker中工作了100次中的99次,以下修改是幂等的
1 2 3 | In [1]: cd /home/jovyan In [2]: from lib.postgres import database_connection |
到目前为止,接受的答案对我来说效果最好。但是,我一直担心的是,我可能会将
因此,具有以下项目结构:
1 2 3 4 5 6 7 8 9 10 11 12 | project |__notebooks |__explore |__ notebook1.ipynb |__ notebook2.ipynb |__ project_path.py |__ explain |__notebook1.ipynb |__project_path.py |__lib |__ __init__.py |__ module.py |
我在每个笔记本子目录(
1 2 3 4 5 6 | 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) |
这样,我只需要在
1 2 | import project_path import lib |
这里需要注意的是,逆转进口是行不通的。这不起作用:
1 2 | import lib import project_path |
因此在进口期间必须小心。