错误从何而起?
此时有这么一个目录结构
我们从a/b
下执行python.exe ./main.py
命令开始
案例: a/b/main.py
导入a/package
if __name__ == "__main__":
# 报错 ModuleNotFoundError: No module named 'package'
import package
# 报错 ImportError: attempted relative import with no known parent package
from ... import package
开始分析问题
问题:python为什么识别不到package
?或者说, 什么样的模块python可以正常导入?
很容易知道, 例如: import time
、import random
肯定能成功,不管在什么目录下都可以导入。
问题:那么为什么他们能导入?
因为这些包的目录进行在sys
模块的sys.path
这个列表类型的变量中存在
执行 F:\Document\研究生总汇\interview\algorithm-coding\.leetcode\other\test\a\b>python ./main.py
if __name__ == "__main__":
import sys
print(sys.path)
import package
输出如下:
['F:\\Document\\研究生总汇\\interview\\algorithm-coding\\.leetcode\\other\\test\\a\\b',
'E:\\MyComputerInstalledSoftwares\\anaconda3\\envs\\jupyterlab\\python39.zip',
'E:\\MyComputerInstalledSoftwares\\anaconda3\\envs\\jupyterlab\\DLLs',
'E:\\MyComputerInstalledSoftwares\\anaconda3\\envs\\jupyterlab\\lib',
'E:\\MyComputerInstalledSoftwares\\anaconda3\\envs\\jupyterlab',
'E:\\MyComputerInstalledSoftwares\\anaconda3\\envs\\jupyterlab\\lib\\site-packages',
'E:\\MyComputerInstalledSoftwares\\anaconda3\\envs\\jupyterlab\\lib\\site-packages\\win32',
'E:\\MyComputerInstalledSoftwares\\anaconda3\\envs\\jupyterlab\\lib\\site-packages\\win32\\lib',
'E:\\MyComputerInstalledSoftwares\\anaconda3\\envs\\jupyterlab\\lib\\site-packages\\Pythonwin'
]
Traceback (most recent call last):
File "F:\Document\研究生总汇\interview\algorithm-coding\.leetcode\other\test\a\b\main.py", line 4, in <module>
import package
ModuleNotFoundError: No module named 'package'
第一个值得关注的点,返回列表的第一个元素为'F:\\Document\\研究生总汇\\interview\\algorithm-coding\\.leetcode\\other\\test\\a\\b'
,可以发现这个路径,就是我们执行 F:\Document\研究生总汇\interview\algorithm-coding\.leetcode\other\test\a\b>python ./main.py
命令时,所处的路径。
结论
因此,我们可知执行的路径会被自动加入sys.path
中,并且其中还包含一些python自带的工具包所处的目录。
这也是为什么同级目录下
的模块导入
,以及python核心包的导入没问题的原因.
问题解决
分析到此为止,很容易得到解决方案,即, 往sys.path
中增加需要扫描包的所处目录。
于是得到如下的代码:
if __name__ == "__main__":
import sys
sys.path.append("../..")
import package
print("包导入成功")
输出:
包导入成功
此外,包搜索路径的添加方式,除了sys.path.append(package_or_module_dir)
的方式,还有其它方式,如下。
扩展:包搜索路径的方法
推荐阅读1
推荐阅读2