Python 管理conda和pip之间依赖关系的最佳实践

Python 管理conda和pip之间依赖关系的最佳实践,python,pip,conda,Python,Pip,Conda,我正在开发一个Python库,它依赖于多个包。我正在努力找到管理所有这些依赖关系的最直接方法,但有以下限制: 其中一些依赖项只能作为conda包提供(从技术上讲,源代码是可用的,但构建过程不是我想要了解的) 其他依赖项仅通过pip可用 我需要在可编辑或开发人员模式下安装我自己的库 我需要定期更新依赖项 初始安装的当前设置: 创建一个新的conda环境 使用conda安装… 使用pip安装-e安装我的库。 此时,一些软件包已经安装,现在由conda管理,另一些则由pip管理。当我想更新我的

我正在开发一个Python库,它依赖于多个包。我正在努力找到管理所有这些依赖关系的最直接方法,但有以下限制:

  • 其中一些依赖项只能作为conda包提供(从技术上讲,源代码是可用的,但构建过程不是我想要了解的)
  • 其他依赖项仅通过pip可用
  • 我需要在可编辑或开发人员模式下安装我自己的库
  • 我需要定期更新依赖项
初始安装的当前设置:

  • 创建一个新的conda环境
  • 使用
    conda安装…
  • 使用
    pip安装-e安装我的库。
此时,一些软件包已经安装,现在由conda管理,另一些则由pip管理。当我想更新我的环境时,我需要:

  • 使用
    conda Update--all
  • 手动更新环境的pip部分
我的问题是这是不稳定的:当我更新所有conda包时,它确保了它管理的包的一致性。但是,我不能保证整个环境保持一致,我只是意识到我遗漏了一些更新,因为我忘了检查环境中pip部分的更新

最好的方法是什么?我想到了:

  • 使用康达:这似乎有效,但我有一些可疑的结果,可能是因为我使用了额外的工具
  • 因为pip可以看到conda软件包,所以初始安装是一致的,这意味着我可以在需要更新时简单地重新安装所有东西。这很管用,但并不十分优雅
中关于管理还需要PyPI来源或
pip
安装的本地软件包的Conda环境的建议是在YAML文件中定义所有依赖项(Conda和pip)。比如:

env.yaml

name: my_env
channels:
 - defaults
dependencies:
 - python=3.8
 - numpy
 - pip
 - pip:
   - some_pypi_only_pkg
   - -e path/to/a/local/pkg
在这种环境中进行更新的工作流是更新YAML文件(我建议将其置于版本控制之下),然后创建新环境或使用

conda env update -f env.yaml
就个人而言,我倾向于创建新的环境,而不是对现有环境进行变异(更新),并在YAML中使用最小的约束(即,
=version
)。当创建一个新的env时,它应该自动拉取最新的一致包。此外,可以保留以前的env实例,以防在开发生命周期中需要回归。

中关于管理同样需要PyPI源代码或
pip安装的本地包的Conda环境的建议是在YAML文件中定义所有依赖项(Conda和pip)。比如:

env.yaml

name: my_env
channels:
 - defaults
dependencies:
 - python=3.8
 - numpy
 - pip
 - pip:
   - some_pypi_only_pkg
   - -e path/to/a/local/pkg
在这种环境中进行更新的工作流是更新YAML文件(我建议将其置于版本控制之下),然后创建新环境或使用

conda env update -f env.yaml

就个人而言,我倾向于创建新的环境,而不是对现有环境进行变异(更新),并在YAML中使用最小的约束(即,
=version
)。当创建一个新的env时,它应该自动拉取最新的一致包。另外,可以保留以前的env实例,以防在开发生命周期中需要回归。

可能是一个很好的起点。是的,这是我阅读以了解当前工作流的内容之一。虽然它在初始安装时运行得相对较好,但当它由conda和pip管理时,很难保持环境的最新状态。将更新逻辑封装在脚本中可以解决您的问题吗?例如,执行update.sh(update.sh包含更新conda/pip环境的所有逻辑)?这可能是一个很好的起点。是的,这是我了解当前工作流程所读的内容之一。虽然它在初始安装时运行得相对较好,但当它由conda和pip管理时,很难保持环境的最新状态。将更新逻辑封装在脚本中可以解决您的问题吗?例如,执行update.sh(update.sh包含更新conda/pip环境的所有逻辑)?谢谢,这似乎是最好的方法。作为后续问题:您将如何建议我指定开发包(linter、测试、文档等)的要求?@ClémentMasson据我所知,这些应该包含在
setup.py
的适当变量下,例如
测试所需的
,类似于任何运行时依赖项。在Conda中工作可以让Conda预先安装工作环境所需的内容(并避免为本机依赖项而烦恼),但是
setup.py
仍然是开发中的包的所有依赖项都应该声明的地方。现在,我找到了一个满足我需要的解决方案:我在requirements.txt文件中单独指定测试需求(setup.py不包含任何依赖项)。这允许使用相同的命令进行更新,如
conda env update-f env.yml-f test_requirements.txt
。这可能不是最干净的做事方式,但它足以满足我的需要。谢谢谢谢,这似乎是最好的方法。作为后续问题:您将如何建议我指定开发包(linter、测试、文档等)的要求?@ClémentMasson据我所知,这些应该包含在
setup.py
的适当变量下,例如
测试所需的
,类似于任何运行时依赖项。在Conda中工作可以让Conda预先安装工作环境所需的内容(并避免为本机依赖项而烦恼),但是,
setup.py
仍然是pac的所有依赖项所在