Python 虚拟环境工作原理解析
Python的虚拟环境用来创建一个相对独立的执行环境,尤其是一些依赖的三方包,最常见的如不同项目依赖同一个但是不同版本的三方包,而且,在虚拟环境中的安装包不会影响到系统的安装包。
不过,其具体的工作原理是怎样的,这里详细介绍。
简介
几乎每个语言都包含自己的包管理工具,这是一个非常复杂的话题,而不同语言选择的实现又略有区别,都会做一些选择和取舍。而Python的包管理解决方案很多,例如pip、virtualenv、pyenv等等。
不过Python语言本身的机制决定了其原理一样。
使用
比较常用的是virtualenv工具,可以参考GuidetoPython中的详细介绍,另外,Python3也提供了自己的虚拟环境创建模块,在创建完成后基本都是通过一个脚本启用独立环境。
例如,如下是使用virtualenv以及venv的虚拟环境创建过程。
$mkdir/tmp/project&&cd/tmp/project $virtualenv--no-site-packagesfoobar $python3-mvenvfoobar
然后,就可以通过sourcefoobar/bin/activate命令激活新环境。
激活脚本
所谓的独立环境,无非就是解决两个问题:A)执行Python解析器所使用的版本;B)使用独立的包。其中前者,在Linux主要是通过PATH环境变量设置,在activate脚本中有如下的内容。
VIRTUAL_ENV="/tmp/project/foobar" exportVIRTUAL_ENV _OLD_VIRTUAL_PATH="$PATH" PATH="$VIRTUAL_ENV/bin:$PATH" exportPATH
也就是将创建的目录添加到PATH环境变量最开始,那么就会优先查找该路径,这样就解决了python解析器独立的问题。
工作原理
如果要使用独立的包,那么关键就是如何在通过import导入时查找到所需的包。
包的查找顺序可以查看Python模块简介中的介绍,简单来说,就是先查看是否是内置模块,然后再从sys.path列表指定的地址中搜索。所以,这里的关键就是sys.path列表的生成。
关于sys.prefix
在Python启动的时候,会先加载一个强依赖的os.py包,而查找这个包是根据解析器的当前路径,以及固定的查找规则来实现的。
简单来说,就是在当前路径加上lib/python${VERSION}/os.py逐层向上查找,注意,如果是64位的操作系统,那么会使用lib64替换掉之前的lib路径。
例如,默认的Python3的解析器路径为/usr/bin/python3.6,那么基础路径是/usr/bin/,所以,其查找顺序为。
/usr/bin/lib64/python3.6/os.py /usr/lib64/python3.6/os.py /lib64/python3.6/os.py
只要在任意路径上找到os.py包,那么就会退出查找,并设置好sys.prefix变量,详细可以通过stracepython查看,会有如下的搜索路径。
stat("/usr/bin/Modules/Setup",0x7fffb7146300)=-1ENOENT(Nosuchfileordirectory) stat("/usr/bin/lib64/python2.7/os.py",0x7fffb71462f0)=-1ENOENT(Nosuchfileordirectory) stat("/usr/bin/lib64/python2.7/os.pyc",0x7fffb71462f0)=-1ENOENT(Nosuchfileordirectory) stat("/usr/lib64/python2.7/os.py",{st_mode=S_IFREG|0644,st_size=25910,...})=0
在查找到os.py之后,会将该路径设置为sys.prefix变量,然后解析器就会到${sys.prefix}/lib/python${VERSION}目录下查找包。
总结
那么其工作原理就是,将python解析器保存在${VENV_PATH}/bin/python,然后创建${VENV_PATH}/lib/python${VERSION}目录,并将相关的文件复制到该目录下,可以复制文件,也可以使用软连接。
其它
如上,如果是Python3就可以直接使用内置的venv模块,其原理与上述的相同,同时通过pyvenv.cfg配置文件来标识原始的home位置,该文件的内容如下。
home=/usr/bin include-system-site-packages=false version=3.6.8
如果include-system-site-packages为true,解释器启动时就会将系统的库添加到sys.path里面,这样在虚拟环境就可以import系统中安装的包了。
注意,Python3提供的venv模块只能根据当前版本创建,不能支持Python2。
参考Virtualenv官方文档,细节可以参考该文档。
CreationofvirtualenvironmentsPython3提供的venv介绍,包括常见参数以及配置文件。
←Older
到此这篇关于Python虚拟环境工作原理解析的文章就介绍到这了,更多相关Python虚拟环境原理内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!