到目前为止,我已经测试了多种在 Python 中 管理项目依赖 项的方法:
- 使用 pip 全局安装所有东西(节省空间,但迟早会给你带来麻烦)
- pip & venv 或 virtualenv(管理起来有点麻烦,但在很多情况下没问题)
- pipenv & pipfile(比 venv/virtualenv 简单一点,但速度慢,而且有些供应商锁定,虚拟环境隐藏在实际项目文件夹之外的其他地方)
- conda 作为包和环境管理器(只要包在 conda 中都可用就很好,混合 pip 和 conda 有点 hacky)
- 诗歌-我没试过这个
- …
我对所有这些(除了 1.)的问题是我的硬盘空间很快就被填满了:我不是开发人员,我在日常工作中使用 Python。因此,我有数百个小项目,它们都各司其职。 Unfortunately, for 80% of projects I need the “big” packages: numpy
, pandas
, scipy
, matplotlib
- you name it .一个典型的小项目大约有 1000 到 2000 行代码,但在 venv/virtualenv/pipenv 中有 800MB 的包依赖。 _实际上_,我有大约 100+ GB 的硬盘驱动器充满了 python 虚拟依赖项。
此外,在每个虚拟环境中安装所有这些需要时间。我在 Windows 中工作,许多软件包无法从 Windows 中的 pip 轻松安装: Shapely
, Fiona
, GDAL
预 编译轮这很简单,但它会破坏大多数工作流程(例如 pip install -r requirements.txt
或 pipenv install
来自 pipfile)。我觉得我有 40% 的时间在安装/更新包依赖项,而只有 60% 的时间在编写代码。 Further, none of these package managers really help with publishing & testing code, so I need other tools eg setuptools
, tox
, semantic-release
, twine
…
我和同事谈过,但他们都面临同样的问题,而且似乎没有人有真正的解决方案。我想知道是否有一种方法可以全局安装一些软件包,例如您在大多数项目中使用的软件包——例如 numpy
, pandas
, scipy
, matplotlib
would be installed with pip in C:\Python36\Lib\site-packages
or with conda
in C:\ProgramData\Miniconda3\Lib\site-packages
- these are well developed packages that don’t often打破东西。如果,我想尽快在我的项目中解决这个问题。
其他东西会放在本地 virtualenv 文件夹中 - 我很想将我当前的工作流程从 pipenv
移动到 conda
。
这种方法是否有意义?至少最近 python 有了很多发展,也许出现了一些我还没有看到的东西。是否有关于如何在这样一个混合的全局本地环境中设置文件的最佳实践指南,例如如何维护 setup.py
, requirements.txt
或 pyproject.toml
共享通过 Gitlab、Github 等开发项目?有哪些陷阱/注意事项?
Chris Warrick 也有 这篇很棒的博客文章,对它进行了非常全面的解释。
[2021 年更新]
由于这篇文章仍然有很多观点,这里是一个主观的 2021 年更新:
[2020 年更新]
半年后,我可以说使用 Conda ( Miniconda ) 解决了我的大部分问题:
- 它在每个系统、WSL、Windows、本机 Linux 等上运行
conda env create -f myenv.yml
在每个平台上都是相同的 - 大多数包已经在 conda-forge 上可用,很容易让自己的包在 conda-forge 上被接受
- 对于那些不在 conda 上的包,我可以在 conda 环境中安装
pip
并使用 pip 从 pypi 添加包。提示:conda update --all -n myenv -c conda-forge
只会更新来自 conda 的包,而不是那些安装了pip
的包。必须使用pip install pack_name --upgrade
手动更新 Pip 安装的依赖项。请注意,在 conda 中使用 pip 安装软件包是一种通常应 避免 的紧急解决方案 - 我可以创建 strict 或 open
environment.yml
,指定 conda 通道优先级、来自 conda 的包和来自 pip 的包 - 我可以在单个语句中从这些 yml 创建 conda 环境,例如在 Gitlab 持续集成中设置开发环境,使用
Miniconda3 Docker
- 这使得测试运行非常简单直接 yml
中的包版本可以根据情况定义为严格或开放。例如,您可以将 env 修复为 Python 3.6,但让它检索此版本范围内的任何安全更新(例如 3.6.9)- 我发现 conda 几乎解决了 Windows 中 c 编译依赖的所有问题; Windows 中的 conda env 确实允许将 python 代码 冻结 为可执行文件(已测试!),该可执行文件可以分发给由于某种原因无法使用包管理器的 Windows 最终用户。
- 关于“大依赖”的问题:我最终创建了许多特定的(即小的)和一些非特定的(即大的)conda 环境:例如,我有一个相当大的
jupyter_env
,其中 jupyter 实验室和我的大部分科学包都已安装(numpy、geos、pandas scipy 等)——每当我需要访问这些工具时,我都会激活它,我可以在一个地方使它们保持最新状态。对于特定包的开发,我有仅用于包依赖项的额外环境(例如packe1_env
)。我总共有大约 10 个环境,这是可以管理的。基本 conda 环境中安装了一些通用工具,例如pylint
。警告:要使 pylint/pycodestyle/autopep8 等在 VS Code 中工作(例如),它必须安装到包含 python-code-dependencies 的相同环境中 - 否则,您将收到未解决的导入警告 - 我用 Windows 的 Chocolatey 包管理器安装了 mini conda。我使用
conda update -n base conda
保持最新状态,我的环境使用conda update --all -n myenv -c conda-forge
每周一次,效果很好! - 新更新: 有一个
--stack
标志可用(截至 2019-02-07 ),允许堆叠 conda 环境,例如conda activate my_big_env
然后conda activate --stack dev_tools_env
许多环境中可用的软件包。但是,请谨慎使用——我发现代码 linter,例如 pylint,必须与被 lint 的代码的依赖项位于相同的环境中 - 新更新 2 :我开始使用
conda
来自Windows Subsystem for Linux
(WSL),这再次显着改善了我的工作流程:包安装速度更快,我可以在直接连接到的 Windows 中使用 VS Code Insiders WSL 和 Linux 环境中 python 包的错误要少得多。 - 附带说明的 另一个更新, Miniconda Docker 允许将本地 conda env 工作流完美地转换为容器化基础设施(CI 和 CD),现在测试了一段时间并且非常满意 - Dockerfile 比 Python Docker 更干净,因为 conda 管理更多依赖工作比 pip 做的。我现在越来越多地使用它,例如,在使用从容器内启动的 jupyter 实验室时。
- 是的,我偶然发现了 conda env 中某些包之间的兼容性问题,但很少见。有两种方法:如果它是一个必须稳定工作的重要环境,启用
conda config --env --set channel_priority strict
这将只安装兼容的版本。对于非常少和罕见的包组合,这可能会导致无法解决的依赖冲突(即无法创建 env)。在这种情况下,我通常会为实验性开发创建较小的环境,使用较少的包并将channel_priority
设置为flexible
(默认值)。 Sometimes, package subsets exists that are easier to solve such asgeoviews-core
(instead ofgeoviews
) ormatplotlib-base
(instead ofmatplotlib
).对于那些无法使用strict
解决的实验性环境,例如conda create -n jupyter_exp_env python=3.6 -c conda-forge
--- ,这也是一种尝试较低 python 版本的好方法。万不得已的方法是使用 pip 安装包,这避免了 conda 的包解析器(但可能会导致环境不稳定和其他问题,您已被警告!)。确保首先在您的环境中明确安装pip
。
一个总体缺点是 conda 在使用大型 conda-forge 通道时变得有点慢。他们正在 努力,但与此同时 conda-forge 指数增长得非常快。
原文由 Alex 发布,翻译遵循 CC BY-SA 4.0 许可协议
问题
您列出了许多没有一种方法可能能够完全解决的问题:
值得庆幸的是,您所描述的并不是困扰包管理器的经典依赖问题——循环依赖、固定依赖、版本控制等。
细节
我在 Windows 上使用 conda 多年,在类似的限制下取得了合理的成功。 Conda 最初旨在使安装 scipy 相关包更容易。它仍然如此。
如果您使用的是“scipy stack”(scipy、numpy、pandas……),conda 是您最可靠的选择。
康达 可以:
康达 不能:
可重现的环境
如果需要,以下步骤应该有助于重现 virtualenvs:
避免 pip 问题
非 conda 工具
康达
但是,如果您想继续使用 conda,可以尝试以下操作:
A. 将工作环境与您的基础环境分开,例如
workenv
。将此视为您的 goto, “global” env 来完成您的大部分日常工作。B. 在工作环境的 克隆 中测试不常见的 pip 包(或重要的 conda 包)的安装
或者,使用
requirements.txt
文件创建包含最小包的新环境C. 将依赖项备份到
requirements.txt
文件,名为environment.yml
每个 virtualenv。 (可选)制作脚本以在每个环境中运行此命令。请参阅有关共享/创建环境文件的 文档。将来从此文件创建环境:出版
打包问题是一个持续的、独立的问题,随着
pyproject.toml
通过 PEP 518 文件的出现而受到关注(参见作者 B. Cannon 的相关 博客文章)。诸如flit
或poetry
之类的打包工具采用了这种现代惯例来进行分发并将它们发布到服务器或打包索引 (PyPI)。pyproject.toml
概念试图摆脱传统的setup.py
特定依赖于setuptools
的文件。依赖关系
像
pipenv
和poetry
这样的工具有一种独特的现代方法来通过“锁定”文件解决依赖性问题。该文件允许您跟踪和重现依赖关系图的状态,这是迄今为止 Python 打包世界中的新事物(请在 此处 查看更多关于 Pipfile 与 setup.py 的信息)。此外,有人声称您仍然可以将这些工具与 conda 结合使用,尽管我尚未测试这些声明的范围。锁定文件尚未标准化,但根据核心开发人员 B. Canon 在关于 Python 打包的未来 的 采访 中所说,(~33m) “我想让我们达到目标。” (见更新)。概括
如果您正在使用 scipy 堆栈中的任何包,请使用 conda( _推荐_):
pipenv
:用于部署和制作Pipfile.lock
poetry
:用于部署和制作poetry.lock
pipenv
:通过pipenv install -e.
开发并使用 twine 手动发布flit
: 自动打包和*发布poetry
: 自动打包 发布也可以看看
pyproject.toml
, 锁定文件 和 工具。pipenv
vs.pip
,37m)和开发环境。更新: