如何知道我自己在 conda(和 pip)中安装了哪些软件包?

Mac*_*iek 6 python pip conda

在我看来,这是一个非常基本的问题,但我没有找到简单的答案。我有两台(实际上更多)PC,在 conda 环境中工作。在某些时候我想执行重大更新,例如P​​ython版本。由于conda显示有很多冲突,我不知道如何处理,我可以使用所需的Python版本创建一个新环境。但是我怎么知道应该在新环境中安装哪些软件包呢?在“旧”中,我有:

  1. 我自己安装的包,
  2. 发现 conda 包是必要的,
  3. 我通过 pip 安装的软件包

那么,当我创建一个新环境时,我应该如何记住我在旧环境中安装了哪些软件包,从而也应该在新环境中安装它们呢?conda env export或者conda list不是很有帮助,因为它们显示所有包(包括它们当前的版本,也许还包括在新的 Python 版本中不再有效的包),并且我想只过滤掉我自己安装的那些包,所以我会知道它们也应该存在于新环境中(并且依赖项将自动安装)。同样的问题也适用于点。

mer*_*erv 9

Conda 对于用户提供的环境约束有一个特定的术语:显式规范。这将对应于您的第一组软件包(用户请求安装)。可以使用该--from-history标志来指定导出的环境应仅包含显式规范:

conda env export --from-history
Run Code Online (Sandbox Code Playgroud)

在这一切之下,它处理$CONDA_PREFIX/conda-meta/history文件(其中包含所有 env-mutating Conda 命令的历史记录)以提取明确请求的约束。还应该注意的是,某些操作(例如使用标志--update-deps)可以触发 Conda 将 env 中的每个包添加到显式规范中。不确定有什么干净的方法可以解决这个问题;可能必须history自己处理文件来检查conda install命令。

然而,这些都不会捕获使用pip.


sin*_*roc 1

+++详细的pip show命令应显示带有Installer. 例如:

$ python -m pip show --verbose setuptools
Name: setuptools
Version: 49.6.0
[...]
Installer: pip
[...]
Run Code Online (Sandbox Code Playgroud)

+++详细的pip list命令应列出当前环境中活动的所有发行版及其安装程序。例如:

$ python -m pip list --verbose
$ .venv/bin/python -m pip list --verbose
Package       Version Location                                  Installer
------------- ------- ----------------------------------------- ---------
pip           20.2.3  /path/to/venv/lib/python3.8/site-packages pip
setuptools    49.6.0  /path/to/venv/lib/python3.8/site-packages pip
Run Code Online (Sandbox Code Playgroud)

+++对于每个安装的发行版都应该有一个INSTALLER文件。例如:

$ cat /path/to/venv/lib/python3.8/site-packages/setuptools-49.6.0.dist-info/INSTALLER
pip
Run Code Online (Sandbox Code Playgroud)

+++一个简短的示例代码,显示如何列出当前环境中的所有发行版及其安装程序:

#!/usr/bin/env python3

import importlib.metadata

def main():
    for distribution in importlib.metadata.distributions():
        installer = None
        for file_path in distribution.files:
            if file_path.name == 'INSTALLER':
                installer = file_path.read_text().strip()
                break
        print(f"{distribution.metadata['Name']} -- {installer}")

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)