首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

该和virtualenv说再见吗?

如果你是一个Python开发人员,你可能听说过Virtual Environments。Virtual Environments是“一个自包含的目录树,其中包含特定版本的Python安装环境,以及一些额外的包”。

它们为什么这么受欢迎?因为,它们解决了一个问题:不需要再将所有包都安装到全局site-packages组成的大杂烩中。相反,每个项目可以在它们自己的“虚拟”环境中安装精确的依赖项版本。

然而,它们也带来了一些问题:

学习曲线:向那些只想进入虚拟环境并编写代码的人解释“虚拟环境”并不总是那么容易

终端隔离:Virtual Environments的激活和停用基于每个终端

认知开销:设置、记住安装位置、激活/停用

为了解决上述问题,我们创造了新的高级工具,如pipenv、poetry、flit和hatch。这些工具通过隐藏pip和Virtual Environments的复杂性来改善这种情况。然而,为了隐藏复杂性,它们本身又变得比较复杂。它们也有自己的API、学习曲线和维护负担。

走进PEP 582 ——Python本地包目录

早在2018年5月,就引入了一个Python增强提案(PEP)来修改Python本身以解决由虚拟环境解决的许多问题,但采用了一种完全不同且比较简单的方法。请注意,该PEP仍然处于草案状态,因此它可能仍然会更改,或者甚至可能根本不会被采纳。

我们来看一下PEP 582[1]中的一段话:

本PEP提案向Python中添加一种机制来自动识别__pypackages__目录,并且优先导入安装在该位置的包,而不是用户或全局site-packages。这将避免创建、激活或停用“虚拟环境”的步骤。Python将使用脚本所在根目录中的__pypackages__,如果这个目录存在的话。

本提案通过搜索本地路径来寻找额外的包,从而有效地解决了Virtual Environments及其高级副本的所有复杂性。

现在就尝试一下

它甚至附带了一个参考CPython实现[2]。

如果你没有时间或者没有兴趣构建一个CPython二进制文件,那么可以尝试我创建的Python包装器的概念验证,称为pythonloc[3](指代“Python local”)。这是一个Python包(少于100行代码),它完成了PEP 582所描述的工作。

pythonloc运行Python,但会从__pypackages__中导入包(如果存在的话)。它还附带piploc,piploc与pip相同,只不过piploc是安装/卸载到__pypackages__。

这里有一个例子。

注意:这可能与你在site packages目录中找到的内容相同,比如~/.local/lib/python3.6/site-packages。

如你所见,piploc将requests包安装到了__pypackages__/3.6/lib/requests。运行python表明它没有找到requests包(这是意料之中的,因为它没有搜索__pypackages__目录)。

要让Python找到它,你可以运行pythonloc,这与运行PYTHONPATH=.:__pypackages__:$PYTHONPATH python是相同的。这样程序运行是就会搜索__pypackages__目录并找到requests安装。

现在,你可以通过运行以下代码来尝试pythonloc:

你可以访问https://github.com/cs01/pythonloc来学习更多。

安装多个依赖项或锁文件

如果你有可用的源代码,并且它有一个setup.py文件,你可以运行

然后运行pythonloc并使所有依赖项可用。

如果你有一个requirements.txt文件,你可以运行

如果你正在使用pipenv,那么你可以通过以下代码生成一个requirements.txt文件

最后,如果你正在使用poetry,那么你可以使用以下代码生成requirements.txt文件

冻结依赖性

虽然我们可以从各种源来安装依赖项,但如果我们正在开发并想要生成一个依赖项列表呢。

随着__pypackages__的出现,你可以使用一种新的工作流来创建依赖项列表,并将__pypackages__本身提交到源代码控制中。这样做实际上可以保证你使用的是相同的版本,因为你使用的是完全相同的源代码。

假设你不想这样做,那么可以运行piploc freeze。但这带来了一个问题。它显示了所有已安装的python包:site-packages中的包以及__pypackages__中的包。这可能不是你想要的,因为它包含的内容比你安装到__pypackages__的内容要多。

你可能只想输出安装到__pypackages__中的包。这正是pipfreezeloc所做的。

它相当于pip freeze,但只输出__pypackages__中的包。这是必需的,因为在pip中没有内置的方法来实现这一点。例如,命令pip freeze --target __pypackages__并不存在。

因此代替运行

你可以运行

结 论

PEP 582是一个提案草案,它引入了一种新的方法来在没有Virtual Environments的情况下安装和隔离包。它还消除了项目位置和环境位置之间的间接关系,因为安装位置始终与项目位置在相同的目录中——在__pypackages__中。

pythonloc(和piploc,pipfreezeloc)是目前可用的PEP 582 Python实现的一个概念验证。

你怎么认为?PEP 582是否应该被批准(请注意,在此过程中我不是决策者,只是一个感兴趣的观察者)? Virtual Environments的依赖性会降低吗?pythonloc改善了你的工作流程吗?

相关连接:

[1]——https://www.python.org/dev/peps/pep-0582/

[2]——https://github.com/kushaldas/cpython/tree/pypackages

[3]——https://github.com/cs01/pythonloc

英文原文:https://qiniumedia.freelycode.com/vcdn/1/%E4%BC%98%E8%B4%A8%E6%96%87%E7%AB%A0%E9%95%BF%E5%9B%BE3/goodbyevirtualenvironments.pdf

译者:一瞬

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190219A06IQB00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券