Python 虚拟环境工作原理解析
作者:悟空小饭 发布时间:2023-02-21 02:18:50
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-packages
为 true
,解释器启动时就会将系统的库添加到 sys.path
里面,这样在虚拟环境就可以 import
系统中安装的包了。
注意,Python3 提供的 venv
模块只能根据当前版本创建,不能支持 Python2 。
参考 Virtualenv 官方文档,细节可以参考该文档。
Creation of virtual environments Python3 提供的 venv 介绍,包括常见参数以及配置文件。
← Older
来源:https://gohalo.me/post/python-virtual-environment-details.html


猜你喜欢
- 一个比较好用的字符串截取函数:function substring($str, $start, $length){ //比较好用字符串截取函
- 前言本文主要给大家介绍了关于Django实现内容缓存的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。1.缓存的简
- 1.1 简介深层神经网络一般都需要大量的训练数据才能获得比较理想的结果。在数据量有限的情况下,可以通过数据增强(Data Augmentat
- unplugin-auto-import的配置和eslint报错解决先上官网:unplugin-auto-importunplugin-au
- 首先介绍一下什么是桑葚图?桑基图(Sankey diagram),即桑基能量分流图,也叫桑基能量平衡图。它是一种特定类型的流程图,图中延伸的
- 插件下载:blueideasearch.xpi首先第一步 说一下怎么样查看firefox插件的源码, 就我上边写的那个东西,把它下载下来.将
- 原理原理:java通过bin-log监控mysql数据变化binlog :binlog 就是binary log,二进制日志文件,这个文件记
- 最近在用python处理Excel表格是遇到了一些问题1, xlwt最多只能写入65536行数据, 所以在处理大批量数据的时候没法使用2,
- 在很多网站都有这样的功能,当点击一个全选按钮之后,所有的复选框都会被选中,再点击之后会取消全选,功能非常的人性化,可以省却很多人力,下面就简
- 一、乱码的原因:1、 client客户端的编码不是utf82、server端的编码不是utf83、database数据库的编码不是utf84
- @num=1; 把num类型转成nvarchar类型 cast(@num as nvarchar(10)) @str='123
- 我是从去年初开始学习web标准的,两年下来也有些心得。最近跳槽了正好闲在家里,写一些出来和大家交流一下。1对于web标准和W3C XHTML
- 装饰器一、介绍器:代表函数的意思。装饰器本质就是是函数功能:装饰其他函数,就是为其他函数添加附加功能 被装饰函数感受不到装饰器的存
- sql不常用函数总结以及事务,增加,删除触发器 distinct 删除重复行 declare @x 申明一个变量 convert(varch
- 开始我们将通过示例介绍偶数列表以及在 Python 中创建偶数列表的不同方法。什么是偶数本教程展示了如何在 Python 中制作偶数列表。
- 记录微信小程序中使用wxss加载图片并实现动画的方式,最终实现loading效果。代码.weui-loading {margin: 0 5p
- 环境:Python+keras,后端为Tensorflow训练集:MNIST对于如何训练一个识别手写数字的神经网络,网上资源十分丰富,并且能
- 本文讲述了python实现删除文件与目录的方法。分享给大家供大家参考。具体实现方法如下:os.remove(path)删除文件 path.
- 本文实例为大家分享了python环境路径设置方法,以及命令行运行python脚本,供大家参考,具体内容如下找Python安装目录,设置环境路
- Microsoft SQL Server 2008将包含用于合并两个行集(rowset)数据的新句法。根据一个源数据表对另一个数据表进行确定