登录        注册
本站基于Django开发,源码 Github 欢迎 Fork、Star。由于站点升级导致评论区留言信息丢失,欢迎前来发表新的评论

别再纠结使用那个Python环境管理器了

Python是非常灵活的编程语言,这一特性也体现在它的环境管理中。但是这也可能意味着您的 Python 安装变得非常混乱。这就出现了大量的环境管理工具试图来控制这种混乱,但是最终可能也会变得更复杂

在这里,我会介绍一下目前一些工具的优缺点,以便您可以对如何安装python环境做出明智的决定。实际上,我们只需要找到自己认为最方便的方式即可:

为什么要做多版本控制以及环境虚拟化

  • 虚拟化是为了避免每个项目之间的依赖冲突,实现项目之间互相隔离的Python环境,提高开发效率
  • 项目应该是可复制的:依赖关系越紧密,开发人员实时复制代码就越容易
  • 自包含=可部署:环境和依赖打包发布越容易,项目部署就越容易

接下来我会从低级工具到高级工具依次讨论优缺点,帮助你做出明智决定为自己省去一些麻烦,我鼓励您考虑所有能够满足您项目需求的方式

到底有哪些管理工具?

venv

从3.3版开始,Python标准库附带了一个简单的内置工具venv

$ /python38/Lib/venv/__init__.py    # 工具源码
# 使用内置工具,在当前位置创建一个名为venv3的虚拟环境
# 如果系统中装了Python多版本,这里最好指定Python版本
$ python3 -m venv --symlinks python3 venv3  # 指定Python版本为python3,python3可直接为Python解释器的位置
$ python -m venv venv3  # 不指定Python版本
$ python3 -m venv --symlinks python3 .  # 直接当前位置创建虚拟环境
$ cd /path/Scripts/     # 进入虚拟环境的位置
$ activate      # 启动虚拟环境
$ deactivate    # 推出虚拟环境

激活后,pip install(独立软件包或来自requirements 文件)将按预期工作。要打包一个虚拟环境以在别处复制,您只需要生成一个包含环境内容的requirements 文件

$ pip freeze > requirements.txt

如果环境处于活动状态,则会生成一个requirements 文件,该文件可以安装到另一个系统上的虚拟环境中

$ pip install -i requirements.txt

优点:

  • Python附带,无需其他工具
  • 创建一个标准虚拟环境:requirements.txt 适用于任何使用 pip 的环境管理器

缺点:

  • 不能集中管理虚拟环境
  • 只能使用pip安装依赖包

改进:

如果你是一个Python老鸟,可以修改源码来更加完美地满足自己的需求,我就这么干过,但是这意味着每次装一个Python解释器,都需要把自己写的init.py文件替换一下,缺点也明显,不过可以自己DIY也是不错的

$ /python38/Lib/venv/__init__.py    # 工具源码

virtualenv

实际上,venv是将virtualenv功能的子模块引入到了Python 3.3+标准库中,使用方其实和venv几乎一样,可以去搜索一下,有很多使用教程的

virtualenv + virtualenvwrapper-win 是极简组合,也是最古老的组合,这也是我习惯用的管理器,其实Python 自带的venv工具,自己也可以把 virtualenvwrapper-win 中的 workon命令融合进去,这个命令是最常用的命令

$ /python38/Lib/venv/__init__.py    # 修改一下venv源码即可,也是很简单的,但是新手最好不要修改

优点:

  • 创建与venv相同的标准虚拟环境,可与大多数Python版本管理工具配合
  • 集成了一些高级功能,例如能够为环境创建引导脚本

缺点:

  • 和venv工具一样

pyenv

pyenv本身仅控制已安装的Python版本,而不控制虚拟环境。当然,在pyenv控制的Python版本中,我们可以轻松地使用venv或virtualenv来构建虚拟环境,不过也可以使用pyenv-virtualenv插件来管理虚拟环境

优点:

  • 一站式管理所有已安装的Python版本
  • 快速设置每个项目的默认Python版本和虚拟环境,自动切换项目目录
  • 等等

缺点:

  • 安装、设置、操作复杂(操作复杂是指功能太多,极简主义就是很少的功能解决特定的需求)

pipenv

Pipenv会自动帮你管理虚拟环境和依赖文件,并且提供了一系列命令和选项来帮助你实现各种依赖和环境管理相关的操作,可以通过Pipfile配置文件,实现更多的操作,甚至是下载指定的Python版本。可以说是环境管理的大集合,无所不能

优点:

  • Python Packaging Authority正式支持
  • 用于项目,虚拟环境和包管理的单一工具
  • 与pyenv和conda配合使用可很好地处理Python环境
  • 每个项目经过验证的确定性依赖

缺点:

  • 与其他管理工具不兼容,因此需要在项目和用户之间一致使用
  • 依赖解析慢

poetry

同样,poetry 包括环境控制和依存关系解析,但poetry 更具体地针对Python软件包开发而不是常规项目控制

也可以说poetry不想pipenv那样包罗万象,想做一个极致的包管理器

优点:

  • 用于项目,虚拟环境和包管理的单一工具
  • 每个项目经过验证的确定性依赖
  • 集成的Python软件包构建/发布工具

缺点:

  • 依赖解析慢
  • 需要特定工具的安装和更新,而不是使用库存包管理器
  • 工具更适合于打包项目,而不是应用程序开发
  • 不与其他环境/程序包管理器兼容

anaconda

Python包管理一直面临一个主要问题-尽管Python包可能需要非Python依赖项(例如,Python中几乎所有数字工具都基于C / C ++),但无法控制这些包有意义地跟踪这些依赖项。较早的sdist(“源代码分发”)软件包分发版只能共享源代码,因此需要在主机上使用兼容的编译器来完全构建,软件包-编译器工具链之间的差异可能会在软件包安装中引入错误。尽管通过迁移到wheel发行版(包括共享对象.so文件等已编译的依赖项)极大地改善了这一点,但是Python的程序包树并未版本跟踪非Python的依赖项(因此,例如,他们实际上并不了解类似编译的依赖项中的版本更改)。

这个以及其他一些问题(例如在pip中缺少严格的依赖解析器)促使Anaconda的发展-一个多合一的Python发行版(尽管其行为与您习惯的普通Python可调用函数相同)和环境管理器称为conda,以及新的程序包分发格式。整个过程都随图形安装程序一起提供,该安装程序还将向启动脚本中注入指令,以便默认的Python来自Anaconda发行版。

这是Anaconda / conda与我们在此讨论的其他管理器之间的最大区别-尽管其他一切都基于pip构建,并使用Python软件包的标准wheel 格式,conda从头开始重新设计环境中打包的方式,并采取了截然不同的设计理念。简而言之:pip可在任何环境中安装python依赖项,而conda可在conda环境中安装任何依赖项。在conda环境中,您可以对依赖项进行细粒度的控制,其代价是只能在conda环境框架中发挥作用-程序包管理器与环境密不可分,并且依赖于包装结构和环境规范与其他Python工具不兼容。相比之下,pip在处理Python依赖项的环境方面是完全通用的(即使在pipenv和poetry)中也被广泛使用),并且可以安装到任何运行Python的环境中,包括conda环境。

所有这些意味着,Anaconda及其相关工具可以真正强大地启动并运行本地环境,并轻松管理自己的项目。因此,它是数据科学家的通用解决方案,这些开发者通常在自己的定制环境中运行代码,并且特别需要对数字包中已编译的依存关系进行干净处理。但是,与其他系统集成要困难得多,尤其是在项目生产部署时。

优点:

  • 集成的Python分发,环境和包管理
  • 有意义地处理非Python依赖项
  • 包括严格的依赖解决方案(相当于pipenv和poetry)
  • 附带有现成的数据科学堆栈
  • 跨平台工作

缺点:

  • 软件包管理器与标准软件包存储库集成
  • 不与任何其他环境管理器集成,没有交叉兼容性
  • 与conda和pip安装的混合搭配可能很难复制
  • 全新的Python软件包开发工具链

docker

就Python环境管理而言,说Docker可能有点奇怪,但它对环境管理至关重要,因此必须包括在内。与其他工具不同,Docker根本就不是Python环境管理器-而是容器管理器。每个Docker容器都运行一个轻量级的环境,其中包括位于隔离资源之上的所有代码,系统工具和库。从开发人员的角度来看,该容器就是运行在Linux环境下的独立计算机,而没有整个虚拟机的资源开销-在同一台计算机上可以同时运行多个容器。全栈开发人员可能会同时为前端,后端和数据库实例运行单独的容器。这使我们可以完全控制代码环境中的所有内容,甚至可以控制底层系统依赖性,还可以创建一个可移植的容器,该容器也即该环境可以在运行Docker的任何地方精确克隆

优点:

  • 完全控制我们所有的依赖关系,直至系统级别-甚至可以使用本文中的任何环境管理器
  • 明确指定所有指令以复制代码环境
  • 容器可以很容易地打包和运输以在生产环境中运行
  • 通用指令可以内置到新的基础映像中,并在项目之间重复使用
  • 可以以编程方式定义在单个docker-compose规范中独立运行的多个服务之间的交互

缺点:

  • 全新的技能学习

总结

我们经常说到依赖管理,其实主要是发布library库依赖和项目应用依赖,分别对应的是setup.py 与 Pipfile(或者requirements.txt)。对于我们初学者很少会发布library库到pypi,所以库依赖我们很少接触。最多的还是利用github发布项目应用,只需要一个Pipfile(或者requirements.txt)依赖文件即可

以上所有的环境管理我都用过,但是最终我还是回归了 virtualenv + virtualenvwrapper-win,因为你的开发环境(也即操作系统)可能不是固定不变的,那么简单快捷不需要配置的环境管理才是最方便的

所以说,大道至简,像我这样的初级程序员一般不会去搞有强依赖性的项目,不需要项目依赖追踪和扩展,使用 virtualenv + virtualenvwrapper-win 就足够方便了,或者自己手动修改一下Python 自带的venv工具,完全已经够用了,再结合一下Docker可以轻松快速地完成项目开发部署

转载请注明: StormSha » 别再纠结使用那个Python环境管理器了

发表我的评论

表情
(0)个小伙伴在吐槽|0条评论
暂时没有评论,欢迎来尬聊!