问题描述
如图所示,对于python,有一个自定义包parent
,它里面还有一个子包child
,当你在parent.module1
中import child.module2
时,vscode会给你报错,说找不到这个包。
当你单独运行module1.py
的时候,可以正常运行,但是当你在parent
包外层的main.py
中import parent.module1
时,就会报错。
详细说明
目录结构为:
-
main.py
-
parent
__init__.py
module1.py
child
__init__.py
module2.py
其中:
main.py
# main.py
import parent.module1
parent.__init__.py
# parent.__init__.py
print('导入了parent包')
child.__init__.py
# child.__init__.py
print('导入了child包')
module1.py
# module1.py
import child.module2
print('导入了module1模块')
module2.py
# module2.py
print('导入了module2模块')
分析原因
当你单独运行module1.py
的时候,可以正常运行,并输出:
导入了child包
导入了module2模块
导入了module1模块
这是因为vscode此时将module1.py
作为相对路径的起点,从而找到了child.module2
的位置。
但是当你在parent
包外层的main.py
中import parent.module1
时,就会报错。
这是因为vscode此时将main.py
作为相对路径的起点,对于main.py
来说,它所在目录下是没有child
包的,只有parent
包,所以找不到,报错。
解决方案
在parent.__init__.py
中添加三行代码,添加完之后如下所示:
# parent.__init__.py
import sys
import os
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
print('导入了parent包')
python找包会在当前路径和sys.path
中去查找,所以可以在导入parent
包的时候,将它的路径加入sys.path
当中,这样就可以找到parent
包的子包了。
同时,因为是在__init__.py
中加的,包内文件就不必每次都将粘贴一次这部分代码。
其中,os.path.realpath(__file__)
获取本文件即parent.__init__.py
的真实路径,os.path.dirname()
将完整路径中的目录名提取出来,去掉其中的文件名。
添加后main.py
运行结果:
导入了parent包
导入了child包
导入了module2模块
导入了module1模块