Python3 Import错误排查:解决PyCharm运行正常但命令行报错的问题
本文针对Python3中常见的import错误进行解析,重点解决在PyCharm中运行正常但在命令行中报错的问题。通过对比同一目录和不同目录下的模块导入情况,深入分析sys.path搜索路径的差异,并提供手动添加路径的解决方案,帮助用户有效排查和修复模块导入问题。
以往编写的代码量较少,此次在阅读论文并运行他人代码时,频繁遇到import相关的问题。本文旨在分享在Ubuntu系统下,使用anaconda3(版本3.6)进行开发时,如何在PyCharm中成功运行的代码,在命令行执行时却出现import错误的经验总结。以下将通过一个简单示例进行说明。
一、同一目录下的import
以下是我的文档结构:在工程tfexe下,存在两个文件夹datasets和parallel。datasets文件夹下包含in文件夹和out.py文件,in文件夹内包含b.py和bb.py两个文件。parallel文件夹下包含a.py和aa.py两个文件。(建议读者先建立此结构以便对照)
a.py文件代码:
def say_hello():
print("hello world!")
aa.py文件代码:可以看到,aa.py调用了a.py中的say_hello()函数。在PyCharm中,这可能会显示错误提示,但实际可以运行。可以通过设置文件夹为source root来消除错误提示,但这并不影响代码执行。
import os
import sys
print("当前的工作目录:",os.getcwd())
print("python搜索模块的路径集合:",sys.path)
from a import say_hello
say_hello()
其他部分暂且无关,此处不予展示。
(1)PyCharm运行结果
右键点击aa.py并运行,观察结果:显然,a.py成功调用了aa.py文件中的say_hello()函数。
可以看到当前的工作目录,即aa.py文件所在的绝对地址。
关注重点:可以看到Python搜索模块的路径集合,特别是前两个路径。在PyCharm中直接运行run时,搜索路径包括整个工程的绝对路径以及运行文件所在的路径。

(2)命令行运行结果
需要切换到parallel文件夹下,然后运行aa.py,观察结果同样正确。
与上述结果相比,工作路径完全相同,但Python的搜索模块路径有何不同?观察第二个路径,会发现缺少了整个工程所在的绝对路径。由于parallel的绝对路径存在,搜索a模块时能够找到,因为a位于parallel绝对路径之下。但如果需要调用其他文件夹的内容,显然会出错,详见下一节。

总结:import同一文件夹下的模块在PyCharm和命令行下均可正常运行。
二、不同目录下的import
b.py文件的内容:
def say_goodbye():
print("goodbye!")
bb.py文件的内容:
import os
import sys
print("当前的工作目录:",os.getcwd())
print("python搜索模块的路径集合",sys.path)
#引入同一文件夹下的模块
from b import say_goodbye
say_goodbye()
# #引入与本文件夹同级的文件夹
# from in2 import c
# c.say()
#引入与本文件夹的上级文件夹同一级的文件夹下的模块
from parallel import a
a.say_hello()
c.py的文件内容:
def say():
print("say yes")
(1)PyCharm运行结果
在PyCharm中,import不同文件夹下的模块竟然成功了。这是为什么呢?观察Python搜索模块的路径结果,其中包含了整个工程tfexe的绝对路径,因此在引入parallel时自然成功,因为parallel在搜索路径上。推测PyCharm自动将整个工程的绝对路径加入sys.path,即Python的模块搜索路径。

但你肯定注意到我注释掉了进入in2模块的部分,为什么注释掉?因为无法运行。为什么无法运行?因为未找到in2模块,这确实尴尬。未找到是因为Python的搜索路径不包含该目录。仔细观察结果,发现只有tfexe的绝对路径和in的绝对路径,in2确实不在其中。如何处理?将其绝对路径添加进去即可。

添加能够搜索到in2的绝对路径:即datasets的绝对路径。
在上面的bb.py中添加以下代码:
#-----这里是加上in2的绝对路径的操作代码------
sys.path.append("/home/syq/PycharmProjects/tfexe/datasets")

从运行结果来看,所有操作均成功,这都归功于sys.path。
(2)命令行运行结果
显然,这里报错了。为什么?提示模块parallel不存在。为什么之前在PyCharm中可以运行,在这里却不行?
我们在命令行中运行注释掉in2部分的代码,即(1)中未更改前的bb.py代码:为了防止混淆,再次贴出bb.py的代码:
import os
import sys
print("当前的工作目录:",os.getcwd())
print("python搜索模块的路径集合",sys.path)
#引入同一文件夹下的模块
from b import say_goodbye
say_goodbye()
# #引入与本文件夹同级的文件夹
# from in2 import c
# c.say()
#引入与本文件夹的上级文件夹同一级的文件夹下的模块
from parallel import a
a.say_hello()
结果:观察到报错,提示parallel模块不存在。显然,观察sys.path的输出,发现缺少了之前的tfexe绝对路径,这就是parallel找不到的原因,因为它根本不在搜索路径上。因此,我在bb.py代码基础上添加了能够搜索到parallel的路径。

修改后的bb.py代码:
import os
import sys
print("当前的工作目录:",os.getcwd())
sys.path.append("/home/syq/PycharmProjects/tfexe")
print("python搜索模块的路径集合",sys.path)
#引入同一文件夹下的模块
from b import say_goodbye
say_goodbye()
# #引入与本文件夹同级的文件夹
# from in2 import c
# c.say()
#引入与本文件夹的上级文件夹同一级的文件夹下的模块
from parallel import a
a.say_hello()
代码运行结果:注意,我将未更改前的bb.py运行结果也放在此处,你可以观察到两者的差异。你会发现,下面的sys.path比更改前的path多了一个可以搜索到parallel的绝对路径,因此能够成功运行。

现在你应该大致明白了。当你遇到import错误时,只需输出sys.path查看是否能搜索到你要加入的模块。如果不能,手动添加即可。
在引入in2模块试试看!
bb.py文件的内容:
import os
import sys
print("当前的工作目录:",os.getcwd())
sys.path.append("/home/syq/PycharmProjects/tfexe")
sys.path.append("/home/syq/PycharmProjects/tfexe/datasets")
print("python搜索模块的路径集合",sys.path)
#引入同一文件夹下的模块
from b import say_goodbye
say_goodbye()
#引入与本文件夹同级的文件夹
from in2 import c
c.say()
#引入与本文件夹的上级文件夹同一级的文件夹下的模块
from parallel import a
a.say_hello()
无论是在命令行还是PyCharm中,均能得到结果。

到此,这篇关于Python3 import问题(PyCharm可以运行,命令行import错误)的文章就介绍到这了。更多相关Python3 import出错内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













