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

Ale*_*lex 12 python dependency-management python-3.x

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

  1. 使用pip安装全局内容(节省空间,但迟早会让您遇到麻烦)
  2. pip&venv或virtualenv(管理有点痛苦,但很多情况下还可以)
  3. pipenv&pipfile(比venv/virtualenv稍微容易一些,但是慢和一些供应商锁定,虚拟环境隐藏在除了实际项目文件夹之外的其他地方)
  4. conda作为包和环境管理器(只要包装都在conda中可用,混合pip和conda有点hacky)
  5. 诗歌 - 我没试过这个
  6. ...

我对所有这些问题(除了1.)的问题在于我的硬盘空间填充速度非常快:我不是开发人员,我使用Python进行日常工作.因此,我有数百个小项目都在做他们的事情.不幸的是,项目的80%,我需要"大"套餐:numpy,pandas,scipy,matplotlib-你的名字.典型的小项目大约有1000到2000行代码,但在venv/virtualenv/pipenv中有800MB的包依赖性.实际上我有大约100多GB的硬盘充满了python虚拟依赖项.

而且,在每个虚拟环境中安装所有这些都需要时间.我在Windows中工作时,许多包不能被轻易从Windows安装点子:Shapely,Fiona,GDAL-我需要预编译的车轮克里斯托夫Gohlke.这很容易,但它会破坏大多数工作流程(例如,pip install -r requirements.txtpipenv install来自pipfile).我觉得我40%安装/更新包依赖,只有60%的时间编写代码.此外,没有这些包管理真正与出版和测试代码的帮助,所以我需要其他工具如setuptools,tox,semantic-release,twine...

我和同事们聊过,但他们都面临着同样的问题,似乎没有人能找到真正的解决方案.我在想,如果有有一些包,例如,你在大多数项目中,全球范围内安装使用的那些的方法-例如numpy,pandas,scipy,matplotlib将在PIP安装C:\Python36\Lib\site-packages或使用condaC:\ProgramData\Miniconda3\Lib\site-packages-这些都是非常发达的包不经常打破一切.如果,我想在我的项目中很快解决这个问题.

其他的事情会去当地的virtualenv文件夹-我很想我的当前工作流从移动pipenvconda.

这种方法有意义吗?至少最近在python中有很多开发,也许还有一些我还没看到的东西.是否有任何的最佳实践指导设置如何文件这样的混合全局-局部环境,例如,如何维护setup.py,requirements.txtpyproject.toml通过Gitlab,Github上共享等发展项目?有什么陷阱/警告?

克里斯·沃里克(Chris Warrick)的这篇精彩博文也完全解释了这一点.

jwo*_*der 8

我想知道是否有一种方法可以获得一些软件包,例如你在大多数项目中使用的软件包,全局安装......其他的东西都会出现在本地的virtualenv文件夹中

是的,virtualenv支持这一点.全局安装全局需要的包,然后,每当您创建virtualenv时,提供--system-site-packages选项,以便生成的virtualenv仍然可以使用全局安装的包.使用tox时,您可以在创建的virtualenvs中通过包含sitepackages=true在相应的[testenv]部分中来设置此选项.


pyl*_*ang 6

问题

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

  • 空间

'我需要“大”包:numpy、pandas、scipy、matplotlib ......实际上我有大约 100 GB 以上的硬盘,里面装满了 python 虚拟依赖项'

  • 时间

...在每个虚拟环境中安装所有这些需要时间

  • 出版

...这些包管理器都没有真正帮助发布和测试代码...

  • 工作流程

我很想将我当前的工作流程从 pipenv 转移到 conda。

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


细节

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

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

康达可以

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

康达不能

  • 帮助发布代码

可重现的环境

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

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

避免 pip 问题

我想知道是否有一种方法可以让一些软件包,例如您在大多数项目中使用的软件包,全局安装......其他东西会放在本地 virtualenv 文件夹中

非 conda 工具

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

康达

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

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

> conda create -n workenv python=3.7 numpy pandas matplotblib scipy
> activate workenv
(workenv)>
Run Code Online (Sandbox Code Playgroud)

B.在工作环境的克隆中测试不常见的 pip 包(或重要的 conda 包)的安装

> conda create --name testenv --clone workenv
> activate testenv
(testenv)> pip install pint
Run Code Online (Sandbox Code Playgroud)

或者,使用requirements.txt文件以最少的包创建新环境

C. 将依赖项备份到一个requirements.txt名为environment.ymlper virtualenv 的类似文件中。(可选)制作脚本以在每个环境中运行此命令。见文档的共享/创建环境文件。将来从此文件创建环境:

> conda create --name testenv --file environment.yml
> activate testenv
(testenv)> conda list
Run Code Online (Sandbox Code Playgroud)

出版

打包问题是一个持续存在的独立问题,随着pyproject.toml文件通过PEP 518的出现而受到关注(参见作者 B. Cannon 的相关博客文章)。诸如flitpoetry已经采用这种现代约定的打包工具进行分发并将它们发布到服务器或打包索引 (PyPI)。该pyproject.toml概念试图从setup.py具有特定依赖性的传统文件转移到setuptools.

依赖关系

像工具pipenvpoetry具有独特现代的方式通过“锁定”文件解决依赖性问题。该文件允许您跟踪和重现依赖关系图的状态,这是迄今为止 Python 打包世界中的新奇事物(在此处查看有关Pipfile 与 setup.py 的更多 信息)。此外,有人声称您仍然可以将这些工具与 conda 结合使用,尽管我尚未测试这些声明的范围。锁定文件尚不规范,但根据核心开发B.佳能在接受采访时Python打包的未来,(〜33米)“我希望让我们在那里。” (见更新)。

概括

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

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

也可以看看

更新

  • 这就是我一直在寻找的,非常感谢!我最初的问题确实很不具体,但你设法解决了我的关键问题。“workenv”的提示、“pyproject.toml”的解释以及“pipenv”/“poetry”依赖图的背景对我来说都是新的,我会尝试一下! (2认同)