我有以下包(和工作目录):
WorkingDirectory--
|--MyPackage--
| |--__init__.py
| |--module1.py
| |--module2.py
|
|--notebook.ipynb
在__init__.py
我有:
import module1
import module2
如果我尝试将MyPackage导入我的笔记本:
import MyPackage as mp
我会得到ModuleNotFoundError: No module named 'module1'
。但是如果我在笔记本外部执行脚本,导入工作正常:如果我在同一目录中创建test.py
并执行与笔记本中相同的操作,则导入将正常工作。如果我在__init__.py
(import MyPackage.module1
)中使用完全限定名称,它将在笔记本内部工作。
导致不同导入行为的原因是什么?
我已确认笔记本的工作目录为WorkingDirectory
。
---更新---------
确切错误是:
C:\Users\Me\Documents\Working Directory\MyPackage\__init__.py in <module>()
---> 17 import module1
ModuleNotFoundError: No module named 'module1'
我的问题与可能的副本不同:
笔记本能够找到包,但只能加载模块。这是通过用module1
代替MyPackage.module1
得出的,并且表明它可能不是与PATH
相关的问题。
我进入WorkingDirectory
并在那里启动了服务器。工作目录应该是包含我的包的文件夹。
答案 0 :(得分:5)
我很确定这个问题是相关的,那里的答案会对你有帮助:https://stackoverflow.com/a/15622021/7458681
tl; dr笔记本服务器的cwd始终是启动服务器的基本路径,无论是否正在运行import os os.getcwd()
。使用import sys sys.path.append("/path/to/your/module/folder")
。
我使用与您指定的结构相同的虚拟模块运行它,在修改sys.path
之前它不会运行,之后会
答案 1 :(得分:2)
两行代码可以解决这个问题,
#list the current work dir
os.getcwd()
#change the current work dir
os.chdir()
更改路径,并导入模块,玩得开心。
答案 2 :(得分:0)
原因是您的MyPackage/__init__.py
是从当前工作目录运行的。例如。在这种情况下来自WorkingDirectory
。这意味着,解释器无法找到名为module1
的模块,因为它不在当前或全局包目录中。
有很少的解决方法。例如,您可以临时覆盖当前的工作目录,例如
cwd = os.getcwd()
csd = __path__[0]
os.chdir(csd)
然后,在完成诸如import module1
之类的所有程序包初始化操作之后,使用os.chdir(cwd)
恢复“呼叫者”的工作目录。
对于我来说,这是一种非常糟糕的方法,因为例如,如果初始化操作引发异常,则将无法恢复工作目录。您需要使用try..except
语句来解决此问题。
另一种方法是使用相对进口。有关更多详细信息,请参见documentation。
以下是MyPackage/__init__.py
的示例,适用于您的示例:
from .module1 import *
但是很少有缺点,可以通过文档凭经验找到。例如,您不能编写类似import .module1
的内容。
更新:
我发现即使从普通的python控制台运行了import MyPackage
,也会引发此异常。不是来自IPython或Jupyter Notebook。因此,这似乎不是IPython本身的问题。
答案 3 :(得分:0)
如果您在 jupyter 环境 上遇到 找不到模块,则必须将其安装在 jupyter 环境中,而不是在命令提示符下安装
在 jupyter 上通过这个命令(对于 Windows)
之后,您可以轻松导入和使用它。 每当你想告诉 jupyter 这是系统命令时,你应该在你的命令之前加上 (!)。