Python 依赖地狱:virtualenv 和全局依赖之间的妥协?

Python dependency hell: A compromise between virtualenv and global dependencies?

到目前为止,我已经在 Python 中测试了 管理我的项目依赖关系 的各种方法:

  1. 使用 pip 全局安装所有东西(节省 space 秒,但迟早会给你带来麻烦)
  2. pip & venv 或 virtualenv(管理起来有点麻烦,但在很多情况下没问题)
  3. pipenv 和 pipfile(比 venv/virtualenv 简单一点,但速度慢,而且有些供应商锁定,虚拟环境隐藏在实际项目文件夹之外的其他地方)
  4. conda 作为包和环境管理器(只要包在 conda 中都可用就很好,混合 pip 和 conda 有点 hacky)
  5. 诗歌-我没试过这个
  6. ...

我对所有这些(除了 1.)的问题是我的硬盘 space 很快就装满了:我不是开发人员,我在日常工作中使用 Python。因此,我有数百个小项目,它们都各司其职。不幸的是,对于 80% 的项目,我需要“大”包:numpypandasscipymatplotlib - 随你便。一个典型的小项目大约有 1000 到 2000 行代码,但在 venv/virtualenv/pipenv 中有 800MB 的包依赖项。 虚拟 我有大约 100+ GB 的硬盘驱动器充满了 python 虚拟依赖项。

此外,在每个虚拟环境中安装所有这些需要时间。我在 Windows 工作,许多包无法从 windows 中的 pip 轻松安装:ShapelyFionaGDAL - 我需要来自 Christoph Gohlke。这很简单,但它会破坏大多数工作流程(例如来自 pipfile 的 pip install -r requirements.txtpipenv install)。我觉得我有 40% installing/updating 包依赖,只有 60% 的时间在写代码。此外,none 这些包管理器确实有助于发布和测试代码,所以我需要其他工具,例如setuptoolstoxsemantic-releasetwine...

我和同事谈过,但他们都面临着同样的问题,而且似乎没有人有真正的解决方案。我想知道是否有一种方法可以包含一些包,例如您在大多数项目中使用的全局安装的 - 例如,numpypandasscipymatplotlib 将在 C:\Python36\Lib\site-packages 中使用 pip 安装或使用C:\ProgramData\Miniconda3\Lib\site-packages 中的 conda - 这些是开发良好的软件包,不会经常破坏东西。如果,我想尽快在我的项目中解决这个问题。

其他东西会放在本地 virtualenv 文件夹中 - 我很想将我当前的工作流程从 pipenv 移动到 conda

这样的方法有意义吗?至少最近 python 有了很大的发展,也许出现了一些我还没有看到的东西。 是否有关于如何在这种混合的全球本地环境中设置文件的最佳实践指南,例如如何维护setup.pyrequirements.txtpyproject.toml用于通过Gitlab、Github等共享开发项目? pitfalls/caveats是什么?

还有来自 Chris Warrick 的 this great blog post 对此进行了相当全面的解释。

[2021 年更新]

由于这个 post 仍然有很多观点,这里是一个主观的 2021 更新:

[2020 年更新]

半年后,我可以说使用 Conda (Miniconda) 解决了我的大部分问题:

一个总体缺点是 conda 在使用大型 conda-forge 通道时变得有点慢。它们是 working on it,但与此同时 conda-forge 索引增长得非常快。

I was wondering if there is an approach to have some packages, e.g. the ones you use in most projects, installed globally ... Other things would go in local virtualenv-folders

是的,virtualenv 支持这个。全局安装全局所需的包,然后,无论何时创建 virtualenv,在适当的 [testenv] 部分提供 [​​=14=]。

我的进度更新:

事实证明,Conda 包管理器比 pipenv 更适合我,原因如下:

  • 默认情况下,全局依赖项可从 conda 虚拟环境中获得
  • 当 installing/updating 依赖项
  • 时它比 pipenv 更快
  • pip 和 conda 的结合确实没有那么大的问题,任何有 conda 包的地方,用 conda 安装,如果没有,只需用 pip 安装
  • 通过使用 environment.yml,可以在几秒钟内在 linux 和 windows 上重新创建环境和依赖项 - environment.yml 允许指定 pip 和单独使用 conda 依赖项(例如,这通过使用 conda 版本解决了 Windows 中 Fiona、Shapely、GDal 等的上述问题)
  • conda解决了跨平台维护packages/dependencies的大部分困难(例如linux、mac、win)
  • 将 conda(例如 miniconda)并排安装到独立 python 通过 conda run
  • 安装和使用 conda 没有问题
  • 如果缺少 environments.yml,可以从 requirements.txt (conda create -n new environment --file requirements.txt)
  • 创建一个环境

不幸的是,创建 environment.yml 的过程似乎并没有在任何地方得到真正一致的描述。过了一会儿,我意识到自动创建的文件 (conda env export environment.yml) 包含尽可能少的依赖项列表(让 conda 在安装时解决其余部分)。否则,environment.yml 将无法跨系统兼容。

无论如何,这个工作流程解决了我上面描述的大部分问题,我很高兴我不再需要使用 pipenv 或 virtualenv。

还有一些缺点,

  1. 需要在多个文件中维护依赖:

    • setup.py
    • environment.yml
  2. 无法在其环境中直接执行程序(例如使用快捷方式),例如这对 pipenv run 没有问题,但是:
    • conda run不会自动source activate env
    • 这是一个open issue,可能会在某个时候解决
  3. cx_freeze 将无法正确包含来自外部 conda env
  4. 的全局依赖项
  5. 如果你需要需要编译的依赖项(例如C-Extensions等),conda会很困难,见下文或

问题

您列出了许多没有一种方法可能能够完全解决的问题:

  • space

'I need the "big" packages: numpy, pandas, scipy, matplotlib... Virtually I have about 100+ GB of my HDD filled with python virtual dependencies'

  • 时间

... installing all of these in each virtual environment takes time

  • 发布中

... none of these package managers really help with publishing & testing code ...

  • 工作流程

I am tempted to move my current workflow from pipenv to conda.

谢天谢地,您所描述的并不是困扰包管理器的经典​​依赖问题——循环依赖、固定依赖、版本控制等


详情

我已经在 Windows 上使用 conda 很多年了,在类似的限制下取得了合理的成功。 Conda 最初旨在使安装 scipy 相关包更容易。它仍然如此。

如果您正在使用“scipy 堆栈”(scipy、numpy、pandas、...),conda 是您最可靠的选择。

Conda 可以:

  • 安装 scipy 包
  • 安装 C 扩展和非 Python 包(需要 运行 numpy 和其他包)
  • 集成 conda 包、conda 通道(你应该看看这个)和 pip 来访问包
  • 与虚拟环境的依赖分离

Conda 不能:

  • 帮助发布代码

可重现环境

如果需要,以下步骤应该有助于重现 virtualenvs:

  • 不要使用 pip 安装 scipy 包。我会依靠 conda 来完成繁重的工作。它更快更稳定。您可以在 conda 环境中 pip 安装不太常见的包。
  • 有时,pip 包可能会与环境中的 conda 包发生冲突(请参阅 release notes 解决此问题)。

避免 pip 问题

I was wondering if there is an approach to have some packages, e.g. the ones you use in most projects, installed globally ... Other things would go in local virtualenv-folders

非 conda 工具

  • pipx 是一个类似 pip 的工具,可以创建全局虚拟环境。
  • virtualenv 传统上为每个项目制作虚拟环境,但幸运的是@jwodder 的回答解释了如何使用全局包。
  • virtualenv-wrapper 促进全局 virtualenvs。

康达

但是,如果您想继续使用 conda,可以尝试以下操作:

一个。将工作环境与您的基础环境分开,例如workenv。将此视为您的 goto,“全局”env 来完成您的大部分日常工作。

> conda create -n workenv python=3.7 numpy pandas matplotblib scipy
> activate workenv
(workenv)>

乙。在工作环境 内测试不常见的 pip 包(或重要的 conda 包)的安装

> conda create --name testenv --clone workenv
> activate testenv
(testenv)> pip install pint

或者,使用 requirements.txt 文件

创建包含最少包的新环境

C。将依赖项备份到每个 virtualenv 名为 environment.yml 的类似 requirements.txt 的文件中。可以选择为每个环境创建一个脚本 运行 这个命令。请参阅 docs 关于 sharing/creating 环境文件。将来从此文件创建环境:

> conda create --name testenv --file environment.yml
> activate testenv
(testenv)> conda list

发布

打包问题是一个持续的、独立的问题,随着 pyproject.toml file via PEP 518 (see related blog post by author B. Cannon). Packaging tools such as flit or poetry 的出现而受到关注,已经采用了这种现代惯例来制作分发并将它们发布到服务器或打包索引(PyPI)。 pyproject.toml 概念试图从具有特定依赖性的传统 setup.py 文件转移到 setuptools.

依赖关系

pipenv and poetry have a unique modern approach to addressing the dependency problem via a "lock" file. This file allows you to track and reproduce the state of your dependency graphs, something novel in the Python packaging world so far (see more on Pipfile vs. setup.py here). Moreover, there are claims that you can still use these tools in conjunction with conda, although I have not tested the extent of these claims. The lock file isn't standardized yet, but according to core developer B. Canon in an interview 等工具 Python 包装的未来 ,(~33m)“我想让我们到达那里。” (查看更新)。

总结

如果您正在使用 scipy 堆栈中的任何包,请使用 conda(推荐):

  • 为了节省 space,时间和工作流程问题使用 conda 或 miniconda。
  • 要解决部署应用程序或在依赖项上使用“锁定”文件的问题,请结合 conda 考虑以下内容:
    • pipenv:用于部署和制作Pipfile.lock
    • poetry:用于部署和制作poetry.lock
  • 要在 PyPI 上发布库,请考虑:
    • pipenv:通过pipenv install -e.开发并使用twine
    • 手动发布
    • flit: 自动打包并*发布
    • poetry:自动打包并发布

另请参阅

  • conda docs 关于管理环境文件。
  • B. Cannon 的播客采访讨论了一般包装问题,pyproject.toml, lock files and tools
  • 播客采访 K. Reitz,讨论包装 toolspipenv 对比 pip,37m)和开发环境。

更新: