【发布时间】:2023-04-06 10:38:01
【问题描述】:
到目前为止,我已经测试了在 Python 中管理我的项目依赖项的各种方法:
- 使用 pip 安装所有全局内容(节省空间,但迟早会给您带来麻烦)
- pip & venv 或 virtualenv(管理起来有点麻烦,但在很多情况下都可以)
- pipenv 和 pipfile(比 venv/virtualenv 简单一点,但速度慢,而且一些供应商锁定,虚拟 env 隐藏在实际项目文件夹之外的其他位置)
- conda 作为包和环境管理器(只要包都在 conda 中可用,那就太好了,混合 pip 和 conda 有点麻烦)
- 诗歌 - 我没试过这个
- ...
我对所有这些(除了 1.)的问题是我的硬盘空间很快就会填满:我不是开发人员,我在日常工作中使用 Python。因此,我有数百个小项目都在做他们的事情。不幸的是,对于 80% 的项目,我需要“大”包:numpy
、pandas
、scipy
、matplotlib
- 随便你。一个典型的小项目大约有 1000 到 2000 行代码,但是在 venv/virtualenv/pipenv 中有 800MB 的包依赖。 实际上我有大约 100+ GB 的 HDD 充满了 python 虚拟依赖项。
此外,在每个虚拟环境中安装所有这些都需要时间。我在 Windows 中工作,许多软件包无法从 Windows 中的 pip 轻松安装:Shapely
、Fiona
、GDAL
- 我需要来自Christoph Gohlke 的预编译轮子。这很容易,但它破坏了大多数工作流程(例如,来自 pipfile 的 pip install -r requirements.txt
或 pipenv install
)。我觉得我有 40% 是在安装/更新包依赖项,而我只有 60% 的时间是在编写代码。此外,这些包管理器都没有真正帮助发布和测试代码,所以我需要其他工具,例如setuptools
、tox
、semantic-release
、twine
...
我和同事谈过,但他们都面临同样的问题,似乎没有人有真正的解决方案。我想知道是否有办法拥有一些包,例如您在大多数项目中使用的那些全局安装的 - 例如,numpy
、pandas
、scipy
、matplotlib
将使用 pip 在C:\Python36\Lib\site-packages
或conda
在C:\ProgramData\Miniconda3\Lib\site-packages
中安装 - 这些是开发良好的软件包,通常不会破坏事物。如果,我想尽快在我的项目中解决这个问题。
其他内容将放在本地 virtualenv 文件夹中 - 我很想将我当前的工作流程从 pipenv
移动到 conda
。
这样的方法有意义吗?至少最近python有很多发展,也许出现了一些我还没有看到的东西。
是否有关于如何在这种混合的全局-本地环境中设置文件的最佳实践指南,例如如何维护setup.py
、requirements.txt
或pyproject.toml
通过Gitlab、Github等共享开发项目?有哪些陷阱/注意事项?
还有来自 Chris Warrick 的 this great blog post 对此进行了非常全面的解释。
[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 安装的依赖项必须使用pip install pack_name --upgrade
手动更新。请注意,在 conda 中使用 pip 安装软件包是一种紧急解决方案,通常应为 avoided - 我可以创建 strict 或 open
environment.yml
,指定 conda 通道优先级、来自 conda 的包和来自 pip 的包 - 我可以在单个语句中从这些 yml 创建 conda 环境,例如在 Gitlab 持续集成中设置开发环境,使用
Miniconda3 Docker
- 这使得测试运行非常简单直接 -
yml
s 中的包版本可以定义为严格或开放,视情况而定。例如。您可以将环境修复为 Python 3.6,但让它检索此版本范围内的任何安全更新(例如 3.6.9) - 我发现conda几乎可以解决Windows中所有c编译依赖的问题; Windows 中的 conda env 确实允许将 freezing python 代码转换为可执行文件(经过测试!),该可执行文件可以分发给由于某种原因无法使用包管理器的 Windows 最终用户。
- 关于“大依赖”的问题:我最终创建了许多特定(即小)和一些非特定(即大)conda 环境:例如,我有一个相当大的
jupyter_env
,其中 jupyter 实验室和大多数安装了我的科学软件包(numpy、geos、pandas scipy 等) - 每当我需要访问这些工具时,我都会激活它,我可以在一个地方保持这些工具的最新状态。对于特定包的开发,我有仅用于包依赖项的额外环境(例如packe1_env
)。我总共有大约 10 个环境,这是可以管理的。一些通用工具安装在基本 conda 环境中,例如pylint
。警告:要使 pylint/pycodestyle/autopep8 等在 VS Code 中工作(例如),它必须安装到包含 python-code-dependencies 的同一环境中 - 否则,您将收到未解决的导入警告 - 我用Chocolatey windows 包管理器安装了 miniconda。我用
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
允许在许多环境中提供一些通用包。但是,请谨慎使用 - 我发现代码 linters,例如 pylint,必须与被 lint 代码的依赖项位于同一环境中 -
新更新 2:我从
Windows Subsystem for Linux
(WSL) 开始使用conda
,这再次显着改善了我的工作流程:软件包安装速度更快,我可以在直接连接到 WSL 的 Windows 中使用 VS Code Insiders并且在 Linux 环境中使用 python 包的错误要少得多。 - 另一个更新附带说明,Miniconda Docker 允许将本地 conda env 工作流完美地转换为容器化基础架构(CI 和 CD),现在对此进行了一段时间的测试并且非常满意 - Dockerfile 更干净与 Python Docker 相比,因为 conda 比 pip 管理更多的依赖项工作。我现在越来越多地使用它,例如,在使用从容器内启动的 jupyter lab 时。
- 是的,我偶然发现了 conda 环境中某些包之间的兼容性问题,但很少见。有两种方法:如果它是一个必须稳定工作的重要环境,请启用
conda config --env --set channel_priority strict
- 这只会安装兼容的版本。如果包组合很少且很少见,这可能会导致无法解决的依赖冲突(即无法创建 env)。在这种情况下,我通常为实验性开发创建更小的环境,使用更少的包并将channel_priority
设置为flexible
(默认值)。有时,存在更容易解决的包子集,例如geoviews-core
(而不是geoviews
)或matplotlib-base
(而不是matplotlib
)。对于strict
无法解决的那些实验性环境,尝试较低的 python 版本也是一种好方法,例如conda create -n jupyter_exp_env python=3.6 -c conda-forge
。不得已的 hack 是使用 pip 安装软件包,这可以避免 conda 的软件包解析器(但可能会导致环境不稳定和其他问题,您已被警告!)。确保首先在您的环境中明确安装pip
。
一个整体的缺点是 conda 在使用大型 conda-forge 通道时会变得有点慢。他们是working on it,但同时 conda-forge 索引的增长速度非常快。
【问题讨论】:
-
如果互联网使用不是问题,您可以考虑直接在 google colab notebooks 上工作,否则您已经谈到的方法将是最好的
-
对 Python 问题始终使用通用 Python 标签
-
“混合 pip 和 conda 有点老套”,您可以使用
conda
虚拟环境并使用pip
安装所有内容? (虽然我 - 也许是无知 - 不知道为什么混合会导致问题) -
是的,但是我又面临一个问题,我需要在 conda 虚拟环境中安装所有东西,这占用了太多空间。另外,我不知道如何在这种混合的 pip/conda env 下更新 requirements.txt 或让 cx_freeze 正确
-
我同意让一切正常工作所需的工作量...对于 pipenv,您将环境变量
PIPENV_VENV_IN_PROJECT
设置为 true,然后pipenv
创建项目目录中的虚拟环境(默认为.venv
)
标签:
python
python-3.x
dependency-management
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python 依赖地狱:virtualenv 和全局依赖之间的妥协? - Python技术站