sys.path是一个列表,存放的是python搜索模块时可以搜索的路径,启动python脚本时,会将执行当前命令所在的目录添加到这个列表中,而且是在列表的最前面,正是因为这个操作,你才能在自己的项目里引用自己编写的模块,当模块名称与第三方模块或系统模块冲突时,优先引用项目里的模块。通常,sys.python里的内容如下所示:
>>> import sys
>>> sys.path
['', '/root/.pyenv/versions/3.6.5/lib/python36.zip', '/root/.pyenv/versions/3.6.5/lib/python3.6', '/root/.pyenv/versions/3.6.5/lib/python3.6/lib-dynload', '/root/.pyenv/versions/3.6.5/lib/python3.6/site-packages']
这里,你重点关注site-packages, 我们安装的第三方库和模块都放在了这里。将sys.path设计为一个可变的列表,而不是元组,就是考虑到了开发人员有很强的动机和需要去修改模块的搜索路径和顺序。
设想,如果你的系统允许用户提交自定义的python脚本,那么你可以为此专门创建一个目录用于存放这些脚本,并将这个目录加入到sys.path中,这样,在你的系统里,你可以像引用其他模块一样去引用用户上传的python脚本来执行他们,这就是本文所提到的修改sys.path的三种方法中的一个,你只需要使用sys.path.append方法将目录添加即可。
另一种修改sys.path的方法时在site-packages目录新建一个.pth文件,帮在文件中加入搜索模块的路径
/root/test
重新启动一个python交互式解释器,输出sys.path,你可以看到/root/test目录也在其中。
第三种修改方法,通过PYTHONPATH环境变量,我使用export 命令设置该环境变量
[root@sheng studyflask]# export PYTHONPATH=/root/studyflask
[root@sheng studyflask]# echo $PYTHONPATH
/root/studyflask
这种设置方法仅仅是为了验证是否凑效,退出终端后,环境变量就会失效,如果你想永久生效,可以在/etc/profile,或者.bashrc中进行设置,设置完PYTHONPATH后,启动一个新的python交互式解释器,输出sys.path
>>> import sys
>>> sys.path
['', '/root/studyflask', '/root/.pyenv/versions/3.6.5/lib/python36.zip', '/root/.pyenv/versions/3.6.5/lib/python3.6', '/root/.pyenv/versions/3.6.5/lib/python3.6/lib-dynload', '/root/.pyenv/versions/3.6.5/lib/python3.6/site-packages']
从灵活性上比较,方法1最为灵活,搜索目录的位置可以通过调用列表的insert方法自由控制,而方法2所添加的搜索目录会加在sys.path的末尾,方法3会加在列表的开头。
从有效范围上比较,方法的生效范围最小,你在脚本里对sys.path进行修改,那么它只对所修改脚本的执行时的进程有效果,其他脚本在执行时不会受到影响,方法2的有效范围就要大一些,假如你有多个python版本,但只在某一个python的site-packages里新建了.pth文件,那么只有当你使用这个python作为启动python脚本的应用程序时,.pth才会生效。生效范围最大的是PYTHONPATH,一旦设置生效,不论你用系统上的哪个python来执行脚本,它都生效,因为python在执行脚本时会自动加载这个环境变量,只要环境变量可以访问,就必然生效。
QQ交流群: 211426309