Python 虚拟环境工作原理解析


Posted in Python onDecember 24, 2020

Python 的虚拟环境用来创建一个相对独立的执行环境,尤其是一些依赖的三方包,最常见的如不同项目依赖同一个但是不同版本的三方包,而且,在虚拟环境中的安装包不会影响到系统的安装包。

不过,其具体的工作原理是怎样的,这里详细介绍。

简介

几乎每个语言都包含自己的包管理工具,这是一个非常复杂的话题,而不同语言选择的实现又略有区别,都会做一些选择和取舍。而 Python 的包管理解决方案很多,例如 pip、virtualenv、pyenv 等等。

不过 Python 语言本身的机制决定了其原理一样。

使用

比较常用的是 virtualenv 工具,可以参考 Guide to Python 中的详细介绍,另外,Python3 也提供了自己的虚拟环境创建模块,在创建完成后基本都是通过一个脚本启用独立环境。

例如,如下是使用 virtualenv 以及 venv 的虚拟环境创建过程。

$ mkdir /tmp/project && cd /tmp/project

$ virtualenv --no-site-packages foobar
$ python3 -m venv foobar

然后,就可以通过 source foobar/bin/activate 命令激活新环境。

激活脚本

所谓的独立环境,无非就是解决两个问题:A) 执行 Python 解析器所使用的版本;B) 使用独立的包。其中前者,在 Linux 主要是通过 PATH 环境变量设置,在 activate 脚本中有如下的内容。

VIRTUAL_ENV="/tmp/project/foobar"
export VIRTUAL_ENV

_OLD_VIRTUAL_PATH="$PATH"
PATH="$VIRTUAL_ENV/bin:$PATH"
export PATH

也就是将创建的目录添加到 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 变量,详细可以通过 strace python 查看,会有如下的搜索路径。

stat("/usr/bin/Modules/Setup", 0x7fffb7146300) = -1 ENOENT (No such file or directory)
stat("/usr/bin/lib64/python2.7/os.py", 0x7fffb71462f0) = -1 ENOENT (No such file or directory)
stat("/usr/bin/lib64/python2.7/os.pyc", 0x7fffb71462f0) = -1 ENOENT (No such file or directory)
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-packagestrue ,解释器启动时就会将系统的库添加到 sys.path 里面,这样在虚拟环境就可以 import 系统中安装的包了。

注意,Python3 提供的 venv 模块只能根据当前版本创建,不能支持 Python2 。

参考 Virtualenv 官方文档,细节可以参考该文档。

到此这篇关于Python 虚拟环境工作原理解析的文章就介绍到这了,更多相关Python 虚拟环境原理内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python文件和目录操作函数小结
Jul 11 Python
python爬虫入门教程之点点美女图片爬虫代码分享
Sep 02 Python
Python fileinput模块使用实例
Jun 03 Python
Python嵌套列表转一维的方法(压平嵌套列表)
Jul 03 Python
Python3非对称加密算法RSA实例详解
Dec 06 Python
windows10下安装TensorFlow Object Detection API的步骤
Jun 13 Python
pyqt5 实现在别的窗口弹出进度条
Jun 18 Python
python版百度语音识别功能
Jul 09 Python
Python命令行click参数用法解析
Dec 19 Python
使用Keras实现Tensor的相乘和相加代码
Jun 18 Python
Python变量格式化输出实现原理解析
Aug 06 Python
用Python爬取某乎手机APP数据
Jun 15 Python
python基于openpyxl生成excel文件
Dec 23 #Python
Python+unittest+requests+excel实现接口自动化测试框架
Dec 23 #Python
用python计算文件的MD5值
Dec 23 #Python
python中lower函数实现方法及用法讲解
Dec 23 #Python
Python类型转换的魔术方法详解
Dec 23 #Python
python3 googletrans超时报错问题及翻译工具优化方案 附源码
Dec 23 #Python
python音频处理的示例详解
Dec 23 #Python
You might like
php 图像函数大举例(非原创)
2009/06/20 PHP
怎样给PHP源代码加密?PHP二进制加密与解密的解决办法
2013/04/22 PHP
codeigniter数据库操作函数汇总
2014/06/12 PHP
YII2.0之Activeform表单组件用法实例
2016/01/09 PHP
PHP动态生成指定大小随机图片的方法
2016/03/25 PHP
PHP 图片处理
2020/09/16 PHP
解决iframe的frameborder在chrome/ff/ie下的差异
2010/08/12 Javascript
40个有创意的jQuery图片和内容滑动及弹出插件收藏集之二
2011/12/31 Javascript
JS代码判断IE6,IE7,IE8,IE9的函数代码
2013/08/02 Javascript
java与javascript之间json格式数据互转介绍
2013/10/29 Javascript
可恶的ie8提示缺少id未定义
2014/03/20 Javascript
Node.js开发之访问Redis数据库教程
2015/01/14 Javascript
JQuery CheckBox(复选框)操作方法汇总
2015/04/15 Javascript
详解原生JavaScript实现jQuery中AJAX处理的方法
2016/05/10 Javascript
利用vue实现模态框组件
2016/12/19 Javascript
js获取浏览器和屏幕的各种宽度高度
2017/02/22 Javascript
微信小程序新手教程之启动页的重要性
2019/03/03 Javascript
基于jQuery实现挂号平台首页源码
2020/01/06 jQuery
利用Python实现网络测试的脚本分享
2017/05/26 Python
Python实现的双色球生成功能示例
2017/12/18 Python
详解Python list和numpy array的存储和读取方法
2019/11/06 Python
Pytoch之torchvision.transforms图像变换实例
2019/12/30 Python
Ranorex通过Python将报告发送到邮箱的方法
2020/01/12 Python
pytorch 常用线性函数详解
2020/01/15 Python
Python3列表List入门知识附实例
2020/02/09 Python
详解H5本地储存Web Storage
2017/07/03 HTML / CSS
绘儿乐产品官方在线商店:Crayola.com
2019/09/07 全球购物
Linux内核的同步机制是什么?主要有哪几种内核锁
2013/01/03 面试题
打架检讨书400字
2014/01/17 职场文书
警察先进个人事迹材料
2014/05/16 职场文书
文明城市创建标语
2014/06/16 职场文书
中学学校门卫岗位职责
2014/08/15 职场文书
四风个人对照检查材料思想汇报(办公室通用版)
2014/10/07 职场文书
场地使用证明模板
2014/10/25 职场文书
导游词之海南-南湾猴岛
2019/10/12 职场文书
PostgreSQL存储过程实用脚本(二):创建函数入门
2021/04/05 PostgreSQL