技术背景

在前面几篇博客中我们介绍了容器的使用(博客1博客2博客3博客4博客5),容器是一种系统级的隔离方案,更多的强调资源上的隔离。而这里我们要介绍的python的虚拟环境,更加强调的是依赖的管理。假如一个python项目需要依赖于numpy==1.20.1的版本,另一个python项目必须依赖于numpy==1.20.2的版本。虽然我们也可以直接使用docker或者其他的容器方案来隔离编程环境,但是这会消耗比较大的资源,因为我们并不需要重新构造一整个系统。因此python也提供了一种更加优雅的解决方案:使用virtualenv来构造一个虚拟的python库的环境,这里面我们可以定制化自己所需的python依赖的版本。比较详细的virtualenv使用方法可以参考官方文档,这里我们仅做一些简单的使用方法的介绍和演示。

安装virtualenv

virtualenv可以直接通过pip来安装和管理,这也大大简化了我们的操作:

[dechin@dechin-manjaro virtualenv]$ python3 -m pip install virtualenv
Collecting virtualenv
Downloading virtualenv-20.4.3-py2.py3-none-any.whl (7.2 MB)
|████████████████████████████████| 7.2 MB 7.5 MB/s
Requirement already satisfied: appdirs<2,>=1.4.3 in /home/dechin/anaconda3/lib/python3.8/site-packages (from virtualenv) (1.4.4)
Collecting distlib<1,>=0.3.1
Downloading distlib-0.3.1-py2.py3-none-any.whl (335 kB)
|████████████████████████████████| 335 kB 8.5 MB/s
Requirement already satisfied: filelock<4,>=3.0.0 in /home/dechin/anaconda3/lib/python3.8/site-packages (from virtualenv) (3.0.12)
Requirement already satisfied: six<2,>=1.9.0 in /home/dechin/anaconda3/lib/python3.8/site-packages (from virtualenv) (1.15.0)
Installing collected packages: distlib, virtualenv
Successfully installed distlib-0.3.1 virtualenv-20.4.3

需要注意的是,这里虽然我们可以通过virtualenv来构造一个纯净的python编程环境,但是python的版本是直接依赖于系统里面所包含的python版本的,我们不能通过virtualenv去构造一个不同的python版本。

virtualenv的使用

virtualenv的使用步骤基本上可以简单划分为:创建环境-激活环境-配置和使用环境-关闭环境,以下分别进行演示。

创建一个虚拟环境

首先我们进入到一个空的目录:

[dechin@dechin-manjaro virtualenv]$ ll
总用量 0

然后直接执行virtualenv envname的命令来构建一个虚拟环境,这里因为我们系统中只有一个python版本,多个python版本的环境需要使用-p选项来进行配置。

[dechin@dechin-manjaro virtualenv]$ virtualenv test_env
created virtual environment CPython3.8.5.final.0-64 in 295ms
creator CPython3Posix(dest=/home/dechin/projects/2021-python/virtualenv/test_env, clear=False, no_vcs_ignore=False, global=False)
seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/dechin/.local/share/virtualenv)
added seed packages: pip==21.0.1, setuptools==54.1.2, wheel==0.36.2
activators BashActivator,CShellActivator,FishActivator,PowerShellActivator,PythonActivator,XonshActivator

执行完成上述指令之后,我们发现在刚才的目录下生成了一个与虚拟环境名称一致的目录名:

[dechin@dechin-manjaro virtualenv]$ ll
总用量 4
drwxr-xr-x 4 dechin dechin 4096 4月 1 21:06 test_env

这就代表虚拟环境已经创建成功了。

激活虚拟环境

在使用一个指定的虚拟环境时,我们需要先激活这个虚拟环境,在虚拟环境目录下的bin目录中,有一个名为activate的可执行文件,就是用来激活虚拟环境的:

[dechin@dechin-manjaro virtualenv]$ source test_env/bin/activate
(test_env)[dechin@dechin-20n2s01200 virtualenv]$ python3 -m pip list
Package Version
---------- -------
pip 21.0.1
setuptools 54.1.2
wheel 0.36.2

我们可以发现一个特点,在激活虚拟环境后,在Linux的命令行之前都会带有一个虚拟环境的名称,用于区分当前所在的虚拟环境。而这里虚拟环境中的python第三方库是几乎没有的,是一个非常纯净的环境,需要我们自己去手动安装与配置环境。

安装与配置python库

在虚拟环境中的操作跟在实际环境中的安装操作是一致的,我们一样也可以使用pip来进行安装包的管理,只是这时候安装所执行的变更只会保存到当前的虚拟环境下,不影响实际环境和其他的虚拟环境。

(test_env)[dechin@dechin-manjaro virtualenv]$ python3 -m pip install numpy
Collecting numpy
Downloading numpy-1.20.2-cp38-cp38-manylinux2010_x86_64.whl (15.4 MB)
|████████████████████████████████| 15.4 MB 295 kB/s
Installing collected packages: numpy
Successfully installed numpy-1.20.2
(test_env)[dechin@dechin-manjaro virtualenv]$ python3 -m pip list
Package Version
---------- -------
numpy 1.20.2
pip 21.0.1
setuptools 54.1.2
wheel 0.36.2

安装完成后,我们看到当前安装的numpy版本号是1.20.2。让我们再打开一个新的终端窗口看下实际环境中的numpy的版本号:

[dechin@dechin-manjaro virtualenv]$ python3 -m pip show numpy
Name: numpy
Version: 1.20.1
Summary: NumPy is the fundamental package for array computing with Python.
Home-page: https://www.numpy.org
Author: Travis E. Oliphant et al.
Author-email: None
License: BSD
Location: /home/dechin/anaconda3/lib/python3.8/site-packages
Requires:
Required-by: xarray, vaex-core, tifffile, tables, statsmodels, seaborn, scipy, scikit-learn, scikit-image, PyWavelets, pytools, pythreejs, pyscf, pyarrow, projectq, plotdigitizer, patsy, pandas, opencv-python, numexpr, numba, mkl-random, mkl-fft, matplotlib, ipyvolume, ipydatawidgets, imageio, hiq-projectq, h5py, cupy, bqplot, Bottleneck, bokeh, bkcharts, astropy, ts, hiqfermion

这里可以区分的是,实际环境中命令行的前面不带有虚拟环境的名称。我们可以看到实际环境下的numpy版本是1.20.1,这样一来我们就用这么一个开销并不是很高的方式,实现了两个不同的numpy版本的共存。

退出虚拟环境

在当前的虚拟环境下,可以直接执行deactivate退出。我们可以测试这样的一个场景:先退出虚拟环境,然后再次进入,以确认刚才的操作被自动的保存到了虚拟环境中:

(test_env)[dechin@dechin-manjaro virtualenv]$ deactivate
[dechin@dechin-manjaro virtualenv]$ source test_env/bin/activate
(test_env)[dechin@dechin-manjaro virtualenv]$ python3 -m pip list
Package Version
---------- -------
numpy 1.20.2
pip 21.0.1
setuptools 54.1.2
wheel 0.36.2
(test_env)[dechin@dechin-manjaro virtualenv]$ deactivate

在上述的执行结果中可以看到,对python环境的变更是永久保存下来了的。这一点上来说操作也比docker容器更加容易,在docker中如果需要持久化的保存一个操作,需要在对容器镜像操作之后,执行额外的commit指令才能保存。因此我们认为virtualenv是一个更加优雅、更加轻量级的,python环境差异化管理的解决方案。

总结概要

在前面几篇博客中我们介绍过docker等容器的编程环境解决方案,但是容器作为一个系统级的隔离方案,其实更加强调的是用户间的隔离,这一点也得益其对NameSpace技术的推广和使用。但是在一部分的场景下,比如快速构造一个纯净的python环境、轻量级的操作实现不同python包的共存,容器技术虽然也可以完成,但是功能显得过于冗余,这就需要使用到本文所介绍的virtualenv这样的一个python依赖管理解决方案。文中我们介绍了virtualenv的安装与基本的使用方法,做了一遍比较完整的演示。

版权声明

本文首发链接为:https://www.cnblogs.com/dechinphy/p/virtualenv.html

作者ID:DechinPhy

更多原著文章请参考:https://www.cnblogs.com/dechinphy/

最新文章

  1. [原创]Linux-day1
  2. delphi.thread.线程循环执行体结构
  3. mvc checked=\&quot;checked\&quot;
  4. Debug过程中的mock (及display窗口的使用)
  5. 【Linux远程管理】Telnet远程连接管理
  6. 关于@property()的那些属性及ARC简介【nonatomic,atomic,assign,retain,strong,weak,copy。】
  7. JavaScrtip之JS最佳实践
  8. ssh无密码登陆(转)
  9. [lua] 你所不知道的lua nil值在可变参数函数中怎么处理!
  10. 1289 大鱼吃小鱼 1305 Pairwise Sum and Divide 1344 走格子 1347 旋转字符串 1381 硬币游戏
  11. 初试pyspider
  12. Django rest framework:__str__ returned non-string (type NoneType) 真正原因
  13. C语言——总结回顾
  14. 关于office在卸载了某一应用之后无法试图使用的功能所在的网络位置
  15. 【微服务目录】.NET Core 微服务介绍
  16. Vue-箭头函数
  17. c#文件管理
  18. Win10如何禁止软件运行?win10禁止软件启动的设置方法!禁止人生日历热点快讯的方法
  19. CSRF(Cross Site Request Forgery, 跨站域请求伪造)
  20. nginx 深入篇

热门文章

  1. cookie &amp; session &amp; token compare
  2. html template tag
  3. Dart: 编码和解码各种存档和压缩格式
  4. CNN专访灵石CTO:Baccarat流动性挖矿能否持续?
  5. NGK又双叒叕送钱了!百万SPC空投不要错过!
  6. SpringBoot整合MyBatis-Plus框架(代码生成器)
  7. Django批量插入数据和分页器
  8. 硬件交互 snmp 使用
  9. 配置Nginx的坑及思路
  10. GetQueuedCompletionStatus客户端前端和server之间的通信