到目前为止,我已经在Python中测试了各种方法来达到manage my project dependencies:

  1. 使用pip安装everything global(节省空间,但迟早会给你带来麻烦)
  2. pip&venv或virtualenv(管理起来有点痛苦,但在很多情况下都可以)
  3. pipenv&pipfile(比venv/virtualenv稍微简单一点,但是速度慢,并且有些供应商锁定,虚拟环境隐藏在实际项目文件夹之外的其他地方)
  4. conda 作为软件包和环境管理器(很好,只要所有软件包都可以在conda 中使用,混合使用pip和conda就有点麻烦了)
  5. 诗歌——我还没试过这个
  6. ...

我对所有这些都有问题(除了1)我的硬盘空间很快就被填满了:我不是开发人员,我在日常工作中使用Python.因此,我有数百个小项目,都做他们的事情.不幸的是,对于80%的项目,我需要"大"包:numpypandasscipymatplotlib——随便你说.一个典型的小项目大约有numpy0到2000行代码,但在venv/virtualenv/pipenv中有800MB的包依赖关系.Virtually我有大约numpy+GB的硬盘,里面充满了python虚拟依赖项.

此外,在每个虚拟环境中安装所有这些都需要时间.我在Windows中工作,许多软件包无法从Windows中的pip轻松安装:ShapelyFionaGDAL-我需要Christoph Gohlke的预编译程序.这很容易,但它 destruct 了大多数工作流(例如,pipfile中的pip install -r requirements.txtpipenv install).我觉得我有40%的时间在安装/更新软件包依赖项,只有60%的时间在编写代码.此外,这些软件包管理器中没有一个真正有助于出版和管理;测试代码,所以我需要其他工具,例如setuptoolstoxsemantic-releasetwine...

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

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

这种方法有意义吗?至少最近python有了很大的发展,也许出现了一些我还没有看到的东西.

克里斯·沃里克(Chris Warrick)也写了this great blog post篇文章,非常全面地解释了这一点.

[Update 2021]

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

  • 如果你是从事数据科学的,(mini)conda仍然值得一看
  • 否则,Poetrypyproject.toml似乎是共同商定的分母

[Update 2020]

与康德共事一年半后,我可以说我的大部分问题都解决了

  • 它在每个系统上运行,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环境,例如使用Miniconda3 Docker在Gitlab Continuous Integration中设置一个开发环境,这使得测试运行非常简单和直接
  • yml年代的软件包版本可以定义为严格版本,也可以定义为开放版本,具体取决于具体情况.例如,您可以将env修复为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代码中工作(例如),必须将其安装到包含python代码依赖项的同一个环境中——否则,您将收到未解决的导入警告
  • 我安装了带有Chocolatey个windows软件包管理器的miniconda.我每周更新一次conda update -n base conda,我的envs每周更新一次conda update --all -n myenv -c conda-forge,效果非常好!
  • New Update:有一个--stack标志(从2019-02-07开始)允许堆叠conda环境,例如conda activate my_big_env然后conda activate --stack dev_tools_env允许在许多环境中提供一些通用包.然而,请谨慎使用——我发现代码linter,比如pylint,必须与被lint的代码的依赖项位于同一个env中
  • New Update 2:我从Windows Subsystem for Linux开始使用conda(WSL),这再次显著改进了我的工作流程:软件包安装速度更快,我可以在直接连接到WSL的Windows中与VS代码内部人员一起工作,并且在Linux环境中python软件包的bug要少得多.
  • Another Update另一方面,Miniconda Docker允许将本地conda env工作流完美地转换为容器化基础设施(CI&CD),对此进行了一段时间的测试,并且非常满意——Dockerfile比Python Docker更干净,因为conda比pip管理更多的依赖项工作.我现在越来越多地使用这个,例如,在使用jupyter lab时,它是从一个容器中开始的.
  • 是的,我在conda env中遇到了某些软件包之间的兼容性问题,但很少.有两种方法:如果它是一个重要的环境,必须稳定工作,启用conda config --env --set channel_priority strict-这将只安装兼容的版本.对于极少且罕见的包组合,这可能会导致无法解决的依赖冲突(即无法创建env).在这种情况下,我通常为实验开发创建更小的环境,使用更少的包,channel_priority设置为flexible(默认值).有时,存在更容易求解的包子集,例如geoviews-core(而不是geoviews)或matplotlib-base(而不是matplotlib).对于那些无法用strict(例如conda create -n jupyter_exp_env python=3.6 -c conda-forge)解决的实验环境,try 较低版本的python也是一种很好的方法.最后一个黑客手段是用pip安装软件包,这避免了conda 的软件包解析器(但可能会导致不稳定的环境和其他问题,您已经收到警告!).确保首先在env中明确安装pip.

一个总的缺点是,使用大型conda forge通道时,conda的速度有点慢.他们是working on it,但同时conda 福吉指数增长非常快.

推荐答案

Problem

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

  • space

"我需要"大"套餐:numpy、pandas、scipy、matplotlib...实际上,我有大约100+GB的硬盘,里面充满了python虚拟依赖项

  • time

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

  • publishing

... 这些软件包管理器都没有真正帮助出版和管理;测试代码...

  • workflow

我很想把我目前的工作流程从pipenv转移到conda .

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


Details

我已经在Windows上使用conda 很多年了,但受到了类似的限制,并取得了合理的成功.Conda最初的设计目的是让安装与scipy相关的软件包变得更容易.现在仍然如此.

如果您使用的是"scipy堆栈"(scipy、numpy、pandas等),conda 是你最可靠的 Select .

conda can:

  • 安装scipy软件包
  • 安装C扩展和非Python软件包(需要运行numpy和其他软件包)
  • integrate conda packages, conda channels (you should look into this) and pip to access packages
  • 虚拟环境中的依赖分离

conda can't:

  • 发布代码的帮助

Reproducible Envs

如果需要,以下步骤应有助于复制VirtualNV:

  • Do not 安装scipy软件包 with pip. I would rely on conda to do the heavy lifting. It is much faster and more stable. You can pip install less common packages inside conda environments.
  • On occasion, a pip package may conflict with conda packages within an environment (see release notes addressing this issue).

Avoid pip-issues

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

非conda 工具

  • pipx是一个类似pip的工具,可以创建全局虚拟环境.
  • virtualenv传统上每个项目都会创建虚拟环境,但谢天谢地@jwodder的回答解释了如何使用全局包.
  • virtualenv-wrapper促进全球虚拟人.

conda

However, if you want to stay with conda , you can try the following:

A.将工作环境与基本环境分开,例如workenv.把这个"Global"Env视为你日常工作的一部分.

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

B. Test installations of uncommon pip packages (or weighty conda packages) within a clone of the working env

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

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

C. Make a backup of dependencies into a requirements.txt-like file called environment.yml per virtualenv. Optionally make a script to run this command per environment. See docs on sharing/creating environment files. Create environments in the future from this file:

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

Publishing

包装问题是一个持续的、独立的问题,随着pyproject.toml file via PEP 518的出现(参见作者B.Cannon的相关blog post),这个问题得到了关注.flitpoetry等打包工具采用了这种现代约定来进行分发,并将其发布到服务器或打包索引(PyPI)中.pyproject.toml概念试图从传统的setup.py个特定依赖文件转移到setuptools个.

Dependencies

Tools like 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 on The future of Python packaging, (~33m) "I'd like to get us there." (See Updates).

Summary

If you are working with any package from the scipy stack, use conda (Recommended):

  • To conserve space, time and workflow issues use conda or miniconda .
  • To resolve deploying applications or using a "lock" file on your dependencies, consider the following in conjunction with conda :
    • pipenv:用于部署和制作Pipfile.lock
    • poetry:用于部署和制作poetry.lock
  • To publish a library on PyPI, consider:
    • pipenv:通过pipenv install -e.开发并使用twine手动发布
    • flit:自动打包并*发布
    • poetry:自动打包和publish

See Also

  • conda docs on managing environment files.
  • 播客采访B.Cannon讨论一般包装问题,pyproject.tomllock filestools.
  • 播客采访K.Reitz,讨论包装tools(pipenvpip37M)和开发环境.

Updates:

Python-3.x相关问答推荐

Gekko优化超出了方程式的界限(由于某种原因,会产生变量)

如何转换Pandas中的数据,以使我 Select 的列名变为行值并增加行?

Numba编译时间呈指数级增长--可以像C编译器一样配置优化级别吗?

为什么 tkinter 在 tkinter 窗口外计算鼠标事件?

如何通过 python 使用 auth no priv 获取 SNMPv3?

使用gekko python的混合整数非线性规划

如何在Pandas 中按条件计算分组?

正则表达式从文本文件中捕获包含制表符/空格和子字符串的部分字符串

从 h264 帧解析数据包时 PyAV 不一致

BeautifulSoup 和 pd.read_html - 如何将链接保存到最终数据框中的单独列中?

如何查找 tensorflow.python.data.ops.dataset_ops.MapDataset 对象的大小或形状,make_csv_dataset 的输出

为什么不切换到 Python 3.x?

为 python3 安装 opencv

判断对 python 3 支持的要求

Python 错误:IndexError:字符串索引超出范围

python total_ordering:为什么使用 __lt__ 和 __eq__ 而不是 __le__?

Python3四舍五入到最接近的偶数

Python在OrderedDict中 Select 第i个元素

如何替换 Python pathlib.Path 中的子字符串?

Django Rest 框架 ListField 和 DictField