我遇到了一个Python'ImportError:No module named ...'错误,尝试从另一个Python包中的模块导入另一个Python包中的Python模块。下图显示了目录结构:
必须注意的是,只有当我从终端运行脚本时才会出现此错误,而在通过PyCharm执行时,此脚本成功运行。从终端执行时的错误如下:
Traceback (most recent call last):
File "social_networks/linked_data.py", line 15, in <module>
from text_analysis.text_refinement import camel_case_split
ImportError: No module named 'text_analysis'
我尝试了不同的导入方式,例如以下内容,但没有取得任何成功:
方法-1:
sys.path.insert(0, os.path.realpath('../text_analysis'))
from text_analysis.text_refinement import camel_case_split
方法-2:
from text_analysis.text_refinement import camel_case_split
这个问题的解决方案是什么?
答案 0 :(得分:1)
将其更改为:
sys.path.insert(0, os.path.realpath('./'))
from text_analysis.text_refinement import camel_case_split
或者:
sys.path.insert(0, os.path.realpath('./text_analysis'))
from text_refinement import camel_case_split
我已在我的机器上重新创建了您的项目结构,并设法使其工作。让我们一步一步走,这样我们就可以弄清楚发生了什么。
首先,我看到你正在PyCharm中开展你的项目。它会自动将项目根添加到PYTHONPATH
。您可以在此thread中详细了解此信息。由于PyCharm会为您处理路径业务,因此您并不需要
sys.path.insert(0, os.path.realpath('../text_analysis'))
让你的代码运行。路径仍将添加,但不会用于定位包。在你的机器上试试吧。我想你会发现它是真的。您可以通过运行
轻松检查路径for path in sys.path:
print(path)
虽然这是有趣的信息,但它没有回答您如何从终端运行它的问题。要理解为什么它不是从脚本运行的,让我们看一下在方法-1中执行(略微修改过的)命令时你将拥有的Python路径:
sys.path.insert(0, os.path.realpath('../text_analysis'))
try:
from text_analysis.text_refinement import camel_case_split
camel_case_split()
except:
for path in sys.path:
print(path)
# output:
# ~/text_analysis (where ../text_analysis path points to)
# ~/social-network-interest-engine/social_networks (where your file is)
# ... (several other irrelevant paths) ...
我们可以看到'../text_analysis'
将一个目录指向所需的内容。如果我们删除了其中一个句号,而是写了'./text_analysis'
,会发生什么?输出似乎是我们需要的:
# output:
# ~/social-network-interest-engine/text_analysis
# ~/social-network-interest-engine/social_networks
但是我们还没有导入这个功能。我们知道这一点,因为我们到达了打印路径的except
部分。查看导入,我们可以看到text_analysis.text_refinement
。如果已经将目录名称添加到路径中,我们是否真的需要说明目录名称?不我们没有。如果我们写
from text_refinement import camel_case_split
相反,我们发现该函数最终被导入。遵循这个逻辑,假设我们想在导入语句中保留text_analysis.text_refinement
(无论出于何种原因),我们也可以不同地添加路径:
sys.path.insert(0, os.path.realpath('./'))
但是,请注意,这种插入路径的方式有些脆弱。起始位置是您拨打python python_file.py
的路径。如果您导航到其他目录,则需要相应地调整os.path.realpath
。你能做什么呢?
sys.path.insert(0, 'full/path/to/application/app/folder')
虽然这假设项目的目录/结构不会改变。
有关路径和导入的更深入概述,您可以阅读有关从不同文件夹here导入内容的更多信息,如果您更喜欢相对路径导入,this是一个有用的线程。当然,official documentation也是一个很好的起点。