|
|
51CTO旗下网站
|
|
移动端

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

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

作者:读芯术来源:读芯术|2019-07-02 06:31

依附之门:“放弃进入这里的所有希望。”

插图:Gustave Doré

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

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

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

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

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

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

可按照先后次序来使用!

2. 什么是虚拟环境?

到底什么是虚拟环境?

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

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

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

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

但丁《神曲·地狱篇》第六章—维吉尔安抚Cerberus

插图:Gustave Doré

3. 使用虚拟环境

(1) 创造虚拟环境

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

  1. test-project/ 
  2. ├── data         
  3. ├── deliver           # Final analysis, code, & presentations 
  4. ├── develop           # Notebooks for exploratory analysis 
  5. ├── src               # Scripts & local project modules 
  6. └── tests 

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

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

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

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

  1. test-project/ 
  2. ├── data        
  3. ├── deliver      
  4. ├── develop      
  5. ├── src      
  6. ├── tests    
  7. └── venv                 # There it is! 

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

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

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

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

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

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

  1. (venv) % deactivate 
  2. %                                    # Old familiar command prompt 

(2) 安装包

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

  1. (venv) % pip list                    # Inside an active environmentPackage    Version 
  2. ---------- ------- 
  3. pip        19.1.1 
  4. setuptools 40.8.0 

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

  1. (venv) % pip install numpy==1.15.3 
  2. (venv) % pip listPackage    Version 
  3. ---------- ------- 
  4. numpy      1.15.3 
  5. pip        19.1.1 
  6. setuptools 40.8.0 

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

  1. #!/usr/bin/env python3 
  2. import numpy as np 

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

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

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

但丁和Virgil穿过Styx河—但丁《神曲·地狱篇》第八章

插图:Gustave Doré

4. 管理环境

(1) 需求文件

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

  1. (venv) % pip freeze 
  2. numpy==1.15.3 

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

  1. (venv) % pip freeze > requirements.txt 

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

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

(2) 复制环境

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

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

  1. test-project/ 
  2. ├── data         
  3. ├── deliver      
  4. ├── develop      
  5. ├── requirements.txt 
  6. ├── src    
  7. └── tests 

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

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

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

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

  1. Sara% cd test-project/ 
  2. Sara% python3 -m venv venv/ 

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

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

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

(3) 故障排除

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

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

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

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

但丁与冰中的叛徒对话——但丁《神曲·地狱篇》第32章

插图:Gustave Doré

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

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

(1) echo $ PATH

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

  1. % echo $PATH 
  2. /usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin 

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

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

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

  1. % python3                           # Activates a Python shell 
  2. >>> import site                       
  3. >>> 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在搜索系统的全局二进制文件之前搜索项目的本地二进制文件。

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

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

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

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

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

(2) 理智检查

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

  1. #!/usr/bin/env python3 
  2. import numpy as np  

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

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

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

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

(3) 环境的目录树

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

  1. test-project/venv/               # Our environment's root directory 
  2. ├── bin 
  3. │   ├── activate                           # Scripts to activate 
  4. │   ├── activate.csh                       # our project's 
  5. │   ├── activate.fish                      # virtual environment. 
  6. │   ├── easy_install 
  7. │   ├── easy_install-3.7 
  8. │   ├── pip 
  9. │   ├── pip3 
  10. │   ├── pip3.7 
  11. │   ├── python -> /usr/local/bin/python    # Symlinks to system-wide 
  12. │   └── python3 -> python3.7               # Python instances. 
  13. ├── include 
  14. ├── lib 
  15. │   └── python3.7 
  16. │       └── site-packages              # Stores local site packages 
  17. └── pyvenv.cfg 

但丁和维吉尔回到了人世间——但丁《神曲·地狱篇》第34章

插图:Gustave Doré

【编辑推荐】

  1. 开发中常用的 25 个JavaScript 单行代码
  2. 一文看懂怎么用Python做数据分析
  3. 别在Java代码里乱打日志了,这才是正确的打日志姿势!
  4. 燃爆!17行Python代码做情感分析?你也可以的
  5. 微软公开 WSL2 使用的 Linux 内核源代码
【责任编辑:赵宁宁 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

16招轻松掌握PPT技巧

16招轻松掌握PPT技巧

GET职场加薪技能
共16章 | 晒书包

292人订阅学习

20个局域网建设改造案例

20个局域网建设改造案例

网络搭建技巧
共20章 | 捷哥CCIE

645人订阅学习

WOT2019全球人工智能技术峰会

WOT2019全球人工智能技术峰会

通用技术、应用领域、企业赋能三大章节,13大技术专场,60+国内外一线人工智能精英大咖站台,分享人工智能的平台工具、算法模型、语音视觉等技术主题,助力人工智能落地。
共50章 | WOT峰会

0人订阅学习

读 书 +更多

程序员密码学

《程序员密码学》涉及密码学的各个研究方向,分组密码、散列函数、公钥密码以及相关的攻击,同时也讲解了密码学算法实现上常用的ASN.编码、...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO播客