Python虚拟环境的原理及使用详解


Posted in Python onJuly 02, 2019

Python的虚拟环境极大地方便了人们的生活。本指南先介绍虚拟环境的基础知识以及使用方法,然后再深入介绍虚拟环境背后的工作原理。

注意:本指南在macOS Mojave系统上使用最新版本的Python 3.7.x。

1. 为什么使用虚拟环境?

虚拟环境为一系列潜在问题提供简单的解决方案,尤其是在以下几个方面:

  1. 允许不同的项目使用不同版本的程序包,从而解决依赖性问题。例如,可以将Project A v2.7用于Project X,并将Package A v1.3用于Project Y。
  2. 通过捕获需求文件中的所有包依赖项,使项目自包含且可重现。
  3. 在没有管理员权限的主机上安装软件包。
  4. 只需要一个项目,无需在系统范围内安装软件包,就能保持全局site-packages /目录整洁。

听起来很方便,不是吗?开始构建更复杂的项目并与其他人协作时,虚拟环境的重要性会凸显出来。很多数据科学家也需要熟悉虚拟环境中与多语言相关的Conda环境。

可按照先后次序来使用!

2. 什么是虚拟环境?

到底什么是虚拟环境?

虚拟环境是用于依赖项管理和项目隔离的Python工具,允许Python站点包(第三方库)安装在本地特定项目的隔离目录中,而不是全局安装(即作为系统范围内的Python的一部分)。

这听起来不错,但到底什么是虚拟环境呢?虚拟环境只是一个包含三个重要组件的目录:

  1. 安装了第三方库的site-packages /文件夹。
  2. 系统上安装的Python可执行文件的symlink符号链接。
  3. 确保执行Python代码的脚本使用在给定虚拟环境中安装的Python解释器和站点包。

最后一点在于会发生一些意想不到的错误,稍后会讲这一点,但现在先看看在实际中如何实际使用虚拟环境。

3. 使用虚拟环境

(1) 创造虚拟环境

假设想要为正在处理的项目创建一个名为test-project/的虚拟环境,该项目具有以下目录树:

test-project/ 
├── data     
├── deliver      # Final analysis, code, & presentations 
├── develop      # Notebooks for exploratory analysis 
├── src        # Scripts & local project modules 
└── tests

需要执行venv模块,它是Python标准库的一部分。

% cd test-project/ 
% python3 -m venv venv/    # Creates an environment called venv/

注意:可使用不同的环境名称替换“venv/”。

瞧!虚拟环境诞生了。现在项目变成:

test-project/ 
├── data    
├── deliver   
├── develop   
├── src   
├── tests  
└── venv         # There it is!

提醒:虚拟环境本身就是一个目录。

唯一要做的事情是通过运行前面提到的脚本来“激活”环境。

% source venv/bin/activate       
(venv) %                # Fancy new command prompt

现在我们位于活动的虚拟环境中(由命令提示符指示,前缀为活动环境的名称)。

我们会像往常一样处理项目,确保项目与系统的其他部分完全隔离。在虚拟环境中,我们无法访问系统范围的站点包,并且无法在虚拟环境之外访问安装包。

完成项目工作时,可以通过以下代码退出环境:

(venv) % deactivate 
%                  # Old familiar command prompt

(2) 安装包

默认情况下,只在新环境中安装pip和setuptools。

(venv) % pip list          # Inside an active environmentPackage  Version 
---------- ------- 
pip    19.1.1 
setuptools 40.8.0

如果想要安装第三方库的特定版本,比如numpyv1.15.3,可像往常一样使用pip。

(venv) % pip install numpy==1.15.3 
(venv) % pip listPackage  Version 
---------- ------- 
numpy   1.15.3 
pip    19.1.1 
setuptools 40.8.0

现在可在脚本或活动的Python shell中导入numpy。例如,假设项目包含以下几行脚本tests / imports-test.py。

#!/usr/bin/env python3 
import numpy as np

直接从命令行运行这个脚本时,可得到:

(venv) % tests/imports-test.py      
(venv) %                 # Look, Ma, no errors!

成功。脚本导入numpy没有故障。

4. 管理环境

(1) 需求文件

使我们的工作成果可被他人重新使用的最简单方法是在项目的根目录(顶层目录)中加入一个需求文件。为此,需要运行pip freeze,以下列出已安装的第三方软件包及其版本号:

(venv) % pip freeze 
numpy==1.15.3

并将输出写入文件,我们称之为requirements.txt。

(venv) % pip freeze > requirements.txt

更新软件包或安装新软件包时,都可使用相同的命令重写需求文件。

现在,任何共享项目的人都可以使用requirements.txt文件,通过复制环境以在系统上运行项目。

(2) 复制环境

等等——究竟是怎么做到的?

想象一下,我们的队友Sara从团队的GitHub存储库中删除了测试项目。在她的系统上,项目的目录树如下所示:

test-project/ 
├── data     
├── deliver   
├── develop   
├── requirements.txt 
├── src  
└── tests

注意到有点不寻常的东西了吗?是的,没错!没有venv /文件夹。

我们已经将它从团队的GitHub存储库中删除,因为它的存在可能会引起麻烦。

这就是使用requirements.txt文件对复制项目代码至关重要的一个原因。

要在机器上运行测试项目,Sara需要做的就是在项目的根目录中创建一个虚拟环境:

Sara% cd test-project/ 
Sara% python3 -m venv venv/

并使用pip install -r requirements.txt将项目的依赖项安装在活动的虚拟环境中。

Sara% source venv/bin/activate 
(venv) Sara% pip install -r requirements.txt 
Collecting numpy==1.15.3 (from -r i (line 1)) 
Installing collected packages: numpy 
Successfully installed numpy-1.15.3

现在,Sara系统上的项目环境与我们的系统完全相同。很整洁,不是吗?

(3) 故障排除

可惜事情并不总是按计划进行,总会遇到一些问题。也许错误地更新了特定的站点包后发现自己处于Dependency Hell的第九级,无法运行单行项目代码。也许它没那么糟糕,可能你会发现自己竟处于第七级。

无论你发现自己处于何种程度,解决问题并再次看到希望的最简单方法是重新创建项目的虚拟环境。

% rm -r venv/              # Nukes the old environment 
% python3 -m venv venv/         # Makes a blank new one 
% pip install -r requirements.txt    # Re-installs

大功告成,多亏了requirements.txt文件,又恢复了正常。然而另一个原因是始终要在项目中列入需求文件。

5. 虚拟环境如何做到这一点?

想了解更多有关虚拟环境的信息吗?比如,活动环境如何使用正确的Python解释程序并如何找到合适的第三方库?

(1) echo $ PATH

这一切都归结为PATH的价值,它告诉shell使用什么Python实例以及在哪里寻找网站包。在基础shell中,PATH看起来或多或少是这样表现的。

% echo $PATH 
/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin

调用Python解释器或运行.py脚本时,shell会按顺序搜索PATH中列出的目录,直到遇到Python实例。要查看PATH首先找到的Python实例,请运行which python3。

% which python3 
/usr/local/bin/python3         # Your output may differ

通过站点模块(这是Python标准库的一部分)查找此Python实例查找站点包的位置也很容易。

% python3              # Activates a Python shell 
>>> import site            
>>> site.getsitepackages()     # Points to site-packages folder['/usr/local/Cellar/python/3.7.3/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages']

运行脚本venv / bin / activate修改PATH,以便shell在搜索系统的全局二进制文件之前搜索项目的本地二进制文件。

% cd ~/test-project/ 
% source venv/bin/activate 
(ven) % echo $PATH~/test-project/venv/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin

现在shell知道如何使用项目的本地Python实例:

(venv) % which python3 
~/test-project/venv/bin/python3

在哪里可以找到项目的本地站点包?

(venv) % python3 
>>> import site 
>>> site.getsitepackages()['~/test-project/venv/lib/python3.7/site-packages']  # Ka-ching

(2) 理智检查

还记得以前的tests / imports-test.py脚本吗?看起来是下面这样:

#!/usr/bin/env python3 
import numpy as np

我们能够在活动环境中运行此脚本,不出现任何问题,是因为环境中的Python实例能够访问项目的本地站点包。

如果运行从项目的虚拟环境外部而来的相同脚本会发生什么?

% tests/imports-test.py        # Look, no active environmentTraceback (most recent call last): 
 File "tests/imports-test.py", line 3, in <module> 
  import numpy as npModuleNotFoundError: No module named 'numpy'

是的,出现了一个错误,但我们应该这样做。如果我们不这样做,那就意味着我们能够从项目外部访问项目的本地站点包,从而破坏了拥有虚拟环境的整个目的。出现错误的事实证明我们的项目与系统的其他部分完全隔离。

(3) 环境的目录树

有一件事可以帮助整理所有这些信息,即清楚地了解环境目录树的外观。

test-project/venv/        # Our environment's root directory 
├── bin 
│  ├── activate              # Scripts to activate 
│  ├── activate.csh            # our project's 
│  ├── activate.fish           # virtual environment. 
│  ├── easy_install 
│  ├── easy_install-3.7 
│  ├── pip 
│  ├── pip3 
│  ├── pip3.7 
│  ├── python -> /usr/local/bin/python  # Symlinks to system-wide 
│  └── python3 -> python3.7        # Python instances. 
├── include 
├── lib 
│  └── python3.7 
│    └── site-packages       # Stores local site packages 
└── pyvenv.cfg

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python之import机制详解
Jul 03 Python
python数据结构链表之单向链表(实例讲解)
Jul 25 Python
详解Python nose单元测试框架的安装与使用
Dec 20 Python
python实现微信跳一跳辅助工具步骤详解
Jan 04 Python
Python实现使用卷积提取图片轮廓功能示例
May 12 Python
在Python中增加和插入元素的示例
Nov 01 Python
如何用python写一个简单的词法分析器
Dec 18 Python
Python利用matplotlib做图中图及次坐标轴的实例
Jul 08 Python
python读取.mat文件的数据及实例代码
Jul 12 Python
Python 3.6 中使用pdfminer解析pdf文件的实现
Sep 25 Python
python GUI库图形界面开发之PyQt5动态(可拖动控件大小)布局控件QSplitter详细使用方法与实例
Mar 06 Python
Python爬虫爬取博客实现可视化过程解析
Jun 29 Python
python输出电脑上所有的串口名的方法
Jul 02 #Python
如何更优雅地写python代码
Jul 02 #Python
Python pip替换为阿里源的方法步骤
Jul 02 #Python
python set内置函数的具体使用
Jul 02 #Python
ZABBIX3.2使用python脚本实现监控报表的方法
Jul 02 #Python
浅谈python 中类属性共享的问题
Jul 02 #Python
如何通过Python实现标签云算法
Jul 02 #Python
You might like
PHP下通过系统信号量加锁方式获取递增序列ID
2009/09/25 PHP
php 生成静态页面的办法与实现代码详细版
2010/02/15 PHP
通过5个php实例细致说明传值与传引用的区别
2012/08/08 PHP
destoon实现调用图文新闻的方法
2014/08/21 PHP
laravel框架 api自定义全局异常处理方法
2019/10/11 PHP
jquery动画2.元素坐标动画效果(创建一个图片走廊)
2012/08/24 Javascript
javascript中数组的定义及使用实例
2015/01/21 Javascript
JavaScript实现的简单拖拽效果
2015/06/01 Javascript
javascript实现网页中涉及的简易运动(改变宽高、透明度、位置)
2015/11/29 Javascript
使用RequireJS库加载JavaScript模块的实例教程
2016/06/06 Javascript
checkbox 选中一个另一个checkbox也会选中的实现代码
2016/07/09 Javascript
AngularJs 国际化(I18n/L10n)详解
2016/09/01 Javascript
Bootstrap基本插件学习笔记之按钮(21)
2016/12/08 Javascript
JS实现物体带缓冲的间歇运动效果示例
2016/12/22 Javascript
详解vue过滤器在v2.0版本用法
2017/06/01 Javascript
node.js中使用Export和Import的方法
2017/09/18 Javascript
layui当点击文本框时弹出选择框,显示选择内容的例子
2019/09/02 Javascript
kafka调试中遇到Connection to node -1 could not be established. Broker may not be available.
2019/09/17 Javascript
利用python将pdf输出为txt的实例讲解
2018/04/23 Python
解决Pandas to_json()中文乱码,转化为json数组的问题
2018/05/10 Python
python 实现将字典dict、列表list中的中文正常显示方法
2018/07/06 Python
对tensorflow 的模型保存和调用实例讲解
2018/07/28 Python
使用Scrapy爬取动态数据
2018/10/21 Python
python实现图片筛选程序
2018/10/24 Python
在Pandas中DataFrame数据合并,连接(concat,merge,join)的实例
2019/01/29 Python
使用Django搭建一个基金模拟交易系统教程
2019/11/18 Python
如何使用Cython对python代码进行加密
2020/07/08 Python
目前不被任何主流浏览器支持的CSS3属性汇总
2014/07/21 HTML / CSS
商务英语大学生职业生涯规划书范文
2014/01/01 职场文书
公司授权委托书范文
2014/08/02 职场文书
大学生个人总结范文
2015/02/15 职场文书
2015毕业生自我评价范文
2015/03/02 职场文书
债务纠纷代理词
2015/05/25 职场文书
小学数学教师研修日志
2015/11/13 职场文书
面试分析分布式架构Redis热点key大Value解决方案
2022/03/13 Redis
TaiShan 200服务器安装Ubuntu 18.04的图文教程
2022/06/28 Servers