1. 代码结构
如下两图所示,当前代码文件分别有三个:test.py
dir_a.py
dir_b.py
,其中主代码为test.py
,该文件在主目录test文件夹下,dir_a.py
dir_b.py
在和test.py
同级的DIR文件夹下。其中test.py
导入了DIR文件夹中的dir_a.py
文件,而dir_a.py
文件导入了同目录下的dir_b.py
文件。
2. 错误的示例
2.1 我一开始的导入代码如下:
test.py
的导入代码部分:
# test.py
from DIR import dir_a
dir_a.py
文件导入dir_b.py
的代码部分:
# dir_a.py
import dir_b
这样的结果是,运行dir_a.py
文件是没问题的,但是运行test.py
时就会报错:ModuleNotFoundError: No module named 'dir_b'
,应该是找不到 dir_b.py
文件。
其实这就是使用相对路径导入模块产生的问题,把相对路径改为绝对路径就行了。注意绝对路径一定是要从当前环境的跟目录开始! 或者可以把dir_a.py
dir_b.py
文件所在的绝对路径添加到sys.path
中。
2.2 将路径添加到sys.path
中(打包不成功)
我在网络上查了好久,产生上面的问题是当前sys.path
中缺少了DIR文件夹路径的问题,可以给添上,将test.py
的导入代码部分修改为如下:
# test.py
import sys
sys.path.append('DIR')
from DIR import dir_a
修改完之后确实不会报错了,但是使用pyinstaller
和Nuitka
打包后,一样还是会报错,如下图,错误原因还是找你到dir_b
错误原因分析:之所以打包后会出现错误,经过我的实验发现,pyinstaller没有把
dir_b.py
文件给打包进去,不知道为啥会出现这种情况,有知道的可以评论告诉我下。
2.3 使用绝对路径
网络上有另一种方案就是只修改dir_a.py
文件中的内容,修改后的dir_a.py
中的导入部分代码:
# dir_a.py
if __package__ is None or __package__ == '':
# uses current directory visibility
import dir_b
else:
# uses current package visibility
from . import dir_b
这样再运行代码dir_a.py
test.py
都不会有问题,而且打包后也不会报错。但是这样代码太臃肿了,建议使用2.4的方案
2.4 终极解决方案
只修改dir_a.py
文件中引入模块的部分,修改为:
# dir_a.py
from DIR import dir_b
这样再运行代码dir_a.py
test.py
都不会有问题。
注意: 其实这里有一个很重要的点,就是绝对路径一定要从当前环境的根目录开始算。上面的写法默认
test
文件夹就是当前环境的根目录,这样的话是没问题的。但是假如test
文件夹的上一级文件夹MyProj
才是编译环境的根目录时(如下图),运行test.py
不会报错,但是运行dir_a.py
是会报错的。这时候dir_a.py
文件中就应该这样改:from test.DIR import dir_b
总结
代码书写时最好是代码都在一个目录下,这样就不会出现上面的问题了。如果必须要用的话,一定要注意模块导入问题,修改成本文提出的方式。