依恋之门:“放弃进入这里的一切希望。”插图:GustaveDoréPython的虚拟环境极大地方便了人们的生活。本指南从虚拟环境的基础知识以及如何使用它们开始,然后深入探讨虚拟环境在幕后的工作原理。注意:本指南在macOSMojave系统上使用最新版本的Python3.7.x。1.为什么要使用虚拟环境?虚拟环境为许多潜在问题提供了简单的解决方案,尤其是在以下方面:允许不同的项目使用不同版本的包,从而解决依赖性问题。例如,您可以将项目Av2.7用于项目X,将包Av1.3用于项目Y。通过在需求文件中捕获所有包依赖项,使项目独立且可重现。在没有管理员权限的主机上安装软件包。只需一个项目,无需在系统范围内安装包,保持全局site-packages/目录整洁。听起来很方便,不是吗?当您开始构建更复杂的项目并与他人协作时,虚拟环境的重要性就会变得显而易见。许多数据科学家还需要熟悉虚拟环境中与多种语言相关的Conda环境。可以按顺序使用!2.什么是虚拟环境?究竟什么是虚拟环境?虚拟环境是一种用于依赖管理和项目隔离的Python工具,允许将Python站点包(第三方库)本地安装在隔离目录中的特定项目中,而不是全局安装(即作为系统范围Python的一部分).这听起来不错,但究竟什么是虚拟环境?虚拟环境只是一个包含三个重要组件的目录:安装了第三方库的site-packages/文件夹。symlink指向系统上安装的Python可执行文件的符号链接。确保执行Python代码的脚本使用安装在给定虚拟环境中的Python解释器和站点包。***关键是可能会发生一些意想不到的错误,稍后会详细介绍,但现在让我们看看虚拟环境在实践中是如何实际使用的。Dante《神曲·地狱篇》第六章——Virgil安抚Cerberus插图:GustaveDoré3.使用虚拟环境(1)创建虚拟环境假设你想为你正在做的项目创建一个名为test-project/的虚拟环境,它有以下内容目录树:test-project/├──data├──deliver#Finalanalysis,code,&presentations├──develop#Notebooksforexploratoryanalysis├──src#Scripts&localprojectmodules└──测试需要执行venv模块,它是Python的一部分标准库。%cdtest-project/%python3-mvenvvenv/#Createsanenvironmentcalledvenv/注意:“venv/”可以替换为不同的环境名称。瞧!一个虚拟环境诞生了。现在项目变成:test-project/├──data├──deliver├──develop├──src├──tests└──venv#Thereitis!提醒:虚拟环境本身就是一个目录。唯一剩下要做的就是通过运行上述脚本来“激活”环境。%sourcevenv/bin/activate(venv)%#Fancynewcommandprompt现在我们处于活动虚拟环境中(由以活动环境名称为前缀的命令提示符表示)。我们照常进行项目,确保项目与系统的其余部分完全隔离。在虚拟环境中,我们无法访问系统范围的站点包,也无法访问虚拟环境之外的安装包。完成项目后,可以使用以下代码退出环境:(venv)%deactivate%#Oldfamiliarcommandprompt(2)安装包默认情况下,新环境中只安装pip和setuptools。(venv)%piplist#InsideanactiveenvironmentPackageVersion----------------pip19.1.1setuptools40.8.0如果要安装特定版本的第三方库,比如numpyv1.15.3,你可以像往常一样使用pip。(venv)%pipinstallnumpy==1.15.3(venv)%piplistPackageVersion----------------numpy1.15.3pip19.1.1setuptools40.8.0现在可以在脚本或活动的Pythonshell导入中使用numpy中。例如,假设项目包含以下几行脚本tests/imports-test.py。#!/usr/bin/envpython3importnumpyasnp当直接从命令行运行这个脚本时,你可以得到:(venv)%tests/imports-test.py(venv)%#Look,Ma,noerrors!成功。该脚本导入numpy没有失败。渡过冥河的但丁和维吉尔——但丁《神曲·地狱篇》第8章插图:古斯塔夫·多雷在顶层目录添加一个需求文件)。为此,您需要运行pipfreeze,它会列出已安装的第三方包及其版本号:(venv)%pipfreezenumpy==1.15.3并将输出写入一个文件,我们称之为requirements.txt。(venv)%pipfreeze>requirements.txt更新包或安装新包时,可以使用相同的命令重写需求文件。现在,任何共享该项目的人都可以使用requirements.txt文件复制环境以在系统上运行该项目。(2)复制环境等等——这到底是怎么做到的?想象一下,我们的队友Sara从团队的GitHub存储库中删除了测试项目。在她的系统上,项目的目录树是这样的:test-project/├──data├──deliver├──develop├──requirements.txt├──src└──tests注意到了一些异常的东西?恩,那就对了!没有venv/文件夹。我们已将其从团队的GitHub存储库中删除,因为它的存在可能会造成麻烦。这就是为什么使用requirements.txt文件对于复制项目代码至关重要的原因之一。要在机器上运行测试项目,Sara需要做的就是在项目的根目录下创建一个虚拟环境:Sara%cdtest-project/Sara%python3-mvenvvenv/并使用pipinstall-rrequirements.txt安装项目的dependencies安装在活动的虚拟环境中。sara%sourcevenv/bin/activate(venv)sara%pipinstall-rrequirements.txtCollectingnumpy==1.15.3(from-ri(line1))Installingcollectedpackages:numpySuccessfullyinstallednumpy-1.15.3现在Sara系统上的项目环境和我们的系统一样。很整洁,不是吗?(3)故障排除不幸的是,事情并不总是按计划进行,而且总是会出现问题。也许在错误地更新了一个特定的站点包之后,您发现自己处于依赖地狱的第九层,无法运行单行代码。也许还不错,也许你会发现自己处于第七层。无论您发现自己处于哪个级别,解决问题并重新看到希望的最简单方法是重新创建项目的虚拟环境。%rm-rvenv/#Nukestheoldenvironment%python3-mvenvvenv/#Makesablanknewone%pipinstall-rrequirements.txt#重新安装完成,感谢requirements.txt文件,一切恢复正常。然而,另一个原因是在项目中总是包含一个需求文件。但丁与冰中叛徒的对话——但丁《神曲·地狱篇》第32章插图:古斯塔夫·多雷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实例,请运行whichpython3。%whichpython3/usr/local/bin/python3#Youroutput可能与站点模块(它是Python标准库的一部分)不同,以查找此Python实例在何处查找站点包。%python3#ActivatesaPythonshell>>>importsite>>>site.getsitepackages()#Pointstosite-packagesfolder['/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/%sourcevenv/bin/activate(ven)%echo$PATH~/test-project/venv/bin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin现在shell知道如何使用项目的本地Python实例:(venv)%whichpython3~/test-project/venv/bin/python3我在哪里可以找到项目的本地站点包?(venv)%python3>>>importsite>>>site.getsitepackages()['~/test-project/venv/lib/python3.7/site-packages']#Ka-ching(2)完整性检查记住之前的tests/imports-test.py脚本?它看起来像这样:#!/usr/bin/envpython3importnumpyasnp我们能够在实时环境中毫无问题地运行这个脚本,因为环境中的Python实例可以访问项目的本地站点包。如果我从项目的虚拟环境之外运行相同的脚本会怎样?%tests/imports-test.py#看,noactiveenvironmentTraceback(mostrecentcalllast):File"tests/imports-test.py",line3,in
