前言:这是一个基础,a文件引入b模块的文件,在python中再简单不过。但是在django平台上去执行这个文件的时候,就会莫名的报错找不到b模块文件。这种问题在一些特殊需求的时候是属于一种疑难杂症的。
本篇文章,就来给大家好好研究和解决一下这个问题。
先来看demo:
【DEMO: 正常无django导入】
文件结构:
a.py:
b.py:
在a文件位置运行a文件:
可以看到是成功导入的。
然后我们换个执行位置,再运行a文件试试:
可以看到仍然是成功导入的。
【DEMO: django项目内】
然后我们引入django平台试试,文件目录如下:
注意,此时的a文件和b文件的位置已经比较复杂了。
然后我们先手动在终端运行a文件来测试(需要采用不同写法导入b):
在a文件位置运行a:
如上图所示,此刻需要用sys.path.append方法临时添加上级目录,才能正常导入,其他写法全部报错。
2. 在其他位置运行a:
如图所示,用sys的方案依然可以成功导入,其他写法基本全会报错。
3. pycharm启动平台,从平台上接口触发的方式,调用subprocess.call方法来使用新进程执行a文件:
如图所示,只有这种写法可以成功导入。
4. 在终端上启动django平台,然后再次用接口触发新进程的方式执行a:
如图,依然可以成功导入。
从这里我们可以得出结论,平台执行 等价于 于在django根目录下使用python命令直接执行。因为manage.py的位置也就是根目录,是django默认命令寻址的初始地。
那么现在问题来了,a脚本的单独本地执行也就是在a文件位置上执行。和平台执行 这俩种情况,能不能让代码不变的方式同时满足呢???
毕竟我们假设a.py文件 就是 自动化脚本,它既需要本地调试,又需要在平台上接口触发的方式执行。
好,公布答案:
这样的写法就可以同时让a.py成功导入b的内容了。
然后我们进阶一下,复杂化一点目录层级:(和培训版本自动化测试平台同样目录设计了)
结果:平台调用成功
本地调试成功:
可以看到,这样的方案,仍然成功导入了。
然后我们就要再复杂一点:(和培训版本自动化测试平台的动态目录一致了)
注意,因为client_50这个50并不确定,所以要做成动态获取:
并且我还打印了下这个 __file__ 大家可以来直观的看到这个__file__是个什么东西。(用re正则来获取这个50,比用split切片要靠谱)
import sys,re print(str(__file__)) try: sys.path.append( 'MyClient/client_%s'% re.findall(r'client_(.\d?)', str(__file__))[0] ) except: sys.path.append('..') from public.b import b b()
结果如下:
平台调用:
本地调试:
如图所示,两种情况均已成功导入。
大家也明白了,两种情况下,__file__的值并不相同,所以要用一个try/except的写法。
欢迎关注:测试开发干货
进群加v:qingwanjianhua