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

总结
代码书写时最好是代码都在一个目录下,这样就不会出现上面的问题了。如果必须要用的话,一定要注意模块导入问题,修改成本文提出的方式。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论