Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Python3从另一个目录中的模块导入本地函数,并在Jupyter笔记本中使用相对导入_Python_Jupyter Notebook_Relative Import - Fatal编程技术网

使用Python3从另一个目录中的模块导入本地函数,并在Jupyter笔记本中使用相对导入

使用Python3从另一个目录中的模块导入本地函数,并在Jupyter笔记本中使用相对导入,python,jupyter-notebook,relative-import,Python,Jupyter Notebook,Relative Import,我有一个类似于下面的目录结构 meta_project project1 __init__.py lib module.py __init__.py notebook_folder notebook.jpynb 在notebook.jpynb中工作时,如果我尝试使用相对导入来访问module.py中的函数function(),请执行以下操作: from ..project1.lib.

我有一个类似于下面的目录结构

meta_project
    project1
        __init__.py
        lib
            module.py
            __init__.py
    notebook_folder
        notebook.jpynb
notebook.jpynb中工作时,如果我尝试使用相对导入来访问
module.py中的函数
function()
,请执行以下操作:

from ..project1.lib.module import function
我得到以下错误:

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
SystemError回溯(最近一次调用)
在()
---->1 from..project1.lib.module导入函数
SystemError:未加载父模块“”,无法执行相对导入
有没有什么方法可以使用相对导入来实现这一点

注意,笔记本服务器是在
meta_项目
目录级别实例化的,因此它应该可以访问这些文件中的信息

另外,请注意,至少最初打算的
project1
没有被视为一个模块,因此没有
\uuuu init\uuuuuuuuuu.py
文件,它只是作为一个文件系统目录。如果问题的解决方案需要将其视为一个模块,并包含一个
\uuuu init\uuuuu.py
文件(即使是一个空白文件),这很好,但这样做不足以解决问题

我在机器之间共享这个目录,相对导入允许我在任何地方都使用相同的代码&我经常使用笔记本进行快速原型设计,因此涉及将绝对路径拼凑在一起的建议不太可能有帮助



编辑:这不同于,它通常在Python3中讨论相对导入,特别是从包目录中运行脚本。这与在jupyter笔记本中工作有关,该笔记本试图调用另一个目录中本地模块中的函数,该目录具有不同的常规和特定方面

我有一个与您几乎相同的示例,我想以一种简单的方式说明相邻模块函数的用法

我的解决方案是通过在笔记本中添加一个类似这样的代码片段来告诉Python这个额外的模块导入路径:

import os
import sys
module_path = os.path.abspath(os.path.join('..'))
if module_path not in sys.path:
    sys.path.append(module_path)
这允许您从模块层次结构导入所需的功能:

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

请注意,如果您还没有空的
\uuuu init\uuuuuy.py
文件,则有必要将它们添加到project1/和lib/文件夹中。

来这里搜索在笔记本电脑中工作时将代码抽象到子模块的最佳实践。我不确定是否有最佳实践。我一直在提出这个建议

这样的项目层次结构:

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

    In [1]: cd ..

    In [2]: from lib.postgres import database_connection
import project_path
import lib
这是因为默认情况下Jupyter笔记本可以解析
cd
命令。注意,这并没有利用Python笔记本的魔力。它只需不加前缀
%bash
即可工作

考虑到我在Docker工作的100次中有99次使用其中一个,下面的修改是幂等的

    In [1]: cd /home/jovyan

    In [2]: from lib.postgres import database_connection

到目前为止,被接受的答案对我来说最有效。然而,我一直担心的是,可能会出现这样的情况:我可能会将
笔记本
目录重构为子目录,需要更改每个笔记本中的
模块路径
。我决定在每个笔记本目录中添加一个python文件来导入所需的模块

因此,具有以下项目结构:

project
|__notebooks
   |__explore
      |__ notebook1.ipynb
      |__ notebook2.ipynb
      |__ project_path.py
   |__ explain
       |__notebook1.ipynb
       |__project_path.py
|__lib
   |__ __init__.py
   |__ module.py
我在每个笔记本子目录(
notebooks/explore
notebooks/explain
)中添加了文件
project\u path.py
)。此文件包含相对导入的代码(来自@metakermit):

这样,我只需要在
project_path.py
文件中进行相对导入,而不是在笔记本中。在导入
lib
之前,笔记本文件只需导入
project\u path
。例如,在
0.0-notebook.ipynb
中:

    In [1]: cd ..

    In [2]: from lib.postgres import database_connection
import project_path
import lib
这里需要注意的是,逆转进口是行不通的。这不起作用:

import lib
import project_path

因此,在导入过程中必须小心。

我自己研究这个主题,并阅读了我建议使用的答案,因为它提供了用于更改当前工作目录的上下文管理器

然后你就有了

导入路径
如果path.path('../lib').isdir():
使用path.path(“..”):
导入库
尽管如此,您可以省略
isdir
语句

在这里,我将添加打印语句,以便于跟踪所发生的事情

导入路径
进口大熊猫
打印(path.path.getcwd())
打印(path.path('../lib').isdir())
如果path.path('../lib').isdir():
使用path.path(“..”):
打印(path.path.getcwd())
导入库
打印('Success!')
打印(path.path.getcwd())
本例中的哪个输出(其中lib位于
/home/jovyan/shared/notebooks/by team/data vis/demos/lib
):


由于该解决方案使用了上下文管理器,因此无论您的内核在单元格之前处于何种状态,也不管导入库代码引发何种异常,您都可以返回到以前的工作目录。

我刚刚找到了这个漂亮的解决方案:

import sys; sys.path.insert(0, '..') # add parent folder path where lib folder is
import lib.store_load # store_load is a file on my library folder
您只需要该文件的一些函数

from lib.store_load import your_function_name
如果python版本>=3.3,您不需要文件夹中的init.py文件

这是我的2美分:

导入系统

映射模块文件所在的路径。在我的情况下,它是桌面 sys.path.append(“/Users/John/Desktop”)

要么导入整个映射模块,要么使用.notation映射类,如mapping.Shipping() 导入映射#mapping.py是我的模块文件的名称

shipit=mapping.shipping()#shipping是我需要在映射模块中使用的类的名称

或者从映射模块导入特定类 从映射导入映射

shipit=shipping()#现在您不必使用.notation

我发现这有助于非常有效地解决此问题。您的项目结构最终会发生轻微的变化
pipenv install python-dotenv
├── .env (this can be empty)
├── ipynb
│   ├── 20170609-Examine_Database_Requirements.ipynb
│   └── 20170609-Initial_Database_Connection.ipynb
└── lib
    ├── __init__.py
    └── postgres.py
import os
import sys

from dotenv import find_dotenv


sys.path.append(os.path.dirname(find_dotenv()))