最近在项目中因为需求原因,需要使用subprocess模块执行shell脚本来启动python文件,结果在模块导入时出现各种报错,经过查找发现,原来是在添加模块搜索路径时使用了相对路径导致的,再结合之前在模块搜索路径上面遇到的问题,特意将相关内容整理了下。
当使用import导入模块时,解释器首先会在内置模块中搜索该模块。如果没有找到,将在变量 sys.path 给出的目录列表中搜索该模块。这里有三个小点需要注意:
1.用pycharm和python解释器启动python文件时,pycharm会自动将项目的根目录添加到 sys.path搜索路径中,而python解释器不会.
如上图所示,我用pycharm和命令行两种方式启动同一.py文件,并在文件中打印sys.path,会发现除了脚本所在目录外,pycharm的模块搜索路径多了'/home/lyz/Desktop/new_VideoFramework2019',即项目的根目录,这就容易出现在pycharm中开发时导包正常,项目部署时导包出错的问题.解决办法就是使用append或insert将项目根目录添加进sys.path模块搜索列表中.
2.sys.path使用insert和append添加模块搜索路径时,由于解释器是按照列表的顺序查找模块的,所以需要考虑假如sys.path模块搜索路径中有两个同名文件时,想用那个文件的问题.
例如将'/home/lyz/Desktop/xxxxxx'目录添加到sys.path中.
1.使用insert添加
2.使用append添加
可以看到使用insert将'/home/lyz/Desktop/xxxxxx'添加到了sys.path的首位,使用append将'/home/lyz/Desktop/xxxxxx'添加到了sys.path的末位.假如你使用append添加完'/home/lyz/Desktop/xxxxxx'目录,想要导入xxxxxx目录下文件a中的函数b,但要是'/home/lyz/Desktop/xxxxxx'目录前面的任何一个目录下有同名文件a,那么解释器就会只在前面目录下的文件a找b,要么出现找不到b的报错,要么出现导入你不想要的b的错误.
3.当一个python文件调用多个python文件时,那么被调用的python文件的模块搜索路径以调用文件为准,和被调用文件的实际位置无关.
1.直接在kill_process文件中打印sys.path
2.通过manage文件调用kill_process文件打印sys.path
可以看到,直接在kill_process文件中打印sys.path,sys.path的首位是'/home/lyz/Desktop/new_VideoFramework2019/subprocess_swtchi',即kill_process文件所在位置,而通过manage文件调用kill_process文件打印sys.path时,sys.path的首位是'/home/lyz/Desktop/new_VideoFramework2019',即manage文件所在位置,由此可见当一个python文件调用多个python文件时,那么被调用的python文件的模块搜索路径以调用文件为准,和被调用文件的实际位置无关,因此,假如我们使用相对路径的方法在sys.path添加模块搜索路径时,一定要注意以启动文件所在位置为准.