pip 和 conda,到底用哪个安装?

发布于:2025-08-12 ⋅ 阅读:(19) ⋅ 点赞:(0)

今天遇到的问题,当我用 pip install pymupdf 时报 × Encountered error while generating package metadata,但是 python -m pip install --prefer-binary pymupdf 却报 Successfully installed pymupdf-1.26.0

若 pip 报错显示在编译某个 C/C++ 源文件失败,通常不是 pip 本身的问题,而是缺系统依赖或没有 wheel。想快速判断“是不是 wheel 的问题”:试 pip install --prefer-binary pymupdf,若成功就说明是 wheel vs source 的差别。

为什么 pip 有时装不下来而 --prefer-binary 可以?

总结:遇到的 pymupdf 情况:如果没有合适的 wheel,pip 会尝试从源代码编译(这需要系统编译工具和 MuPDF 的头文件/库),编译失败就装不上;--prefer-binary 会让 pip 尽可能选择一个已有的 wheel(哪怕是旧版本),从而成功。

先来学一下 Python Package Formats

你会在包索引( 如 PyPI) 上找到两种格式的文件: 源发行版 ,简称 sdists,以及 二进制发行版 ,通常称为轮子 。例如,pip 23.3.1 的 PyPI 页面允许下载两个文件,pip-23.3.1.tar.gzpip-23.3.1-py3-none-any.whl。前者是 sdist,后者是轮子。在 PyPI(或其他地方)上发布包时,应该始终上传一个 sdist 和一个或多个 wheel。

  • PyPI 上每个包可能提供多种分发格式:wheel(二进制)sdist(源码)wheel 可以直接安装;sdist 需要在本机执行编译步骤(如果包包含扩展模块)。如果你的平台/Python 版本没有对应的 wheel,pip 就会下载 sdist 并尝试 build

  • pip install pymupdf:若 PyPI 上没有与当前 Python/平台匹配的 wheel,pip 会尝试构建(失败常见原因:缺少编译器、python-dev 头文件、或缺少第三方 C 库/头文件)。有 wheel 时直接安装速度又快又稳。PyMuPDF 文档也明确“如果有 wheel 则会从 wheel 安装”。

    在这里插入图片描述

  • --prefer-binary 的作用是优先选择二进制包(即使那不是最新版本),从而避免回退到源代码编译导致的失败。若没有任何可用 wheel,则仍然会回退(或失败)。(pip 文档有 –prefer-binary 的说明) 。

什么是源代码发行版?

从概念上讲,源代码发行版是原始形式的源代码存档。具体来说,sdist 是一个 .tar.gz 存档,其中包含源代码和一个名为 PKG-INFO 的附加特殊文件,该文件保存项目元数据。此文件的存在有助于打包工具提高效率,因为不需要自己计算元数据。PKG-INFO 文件遵循核心元数据规范中指定的格式,不打算手动编写。

当标准 Python 包安装程序 pip 找不到要安装的轮子时,它将回退到下载源代码发行版,从中编译轮子并安装轮子。此外,sdist 经常被下游打包者(例如 Linux 发行版、macOS 上的 Conda、Homebrew 和 MacPorts 等)用作包源,出于各种原因,他们可能更喜欢它们,例如从 Git 存储库中提取。

什么是轮子?

从概念上讲,滚轮恰好包含安装包时需要复制的文件

对于 扩展模块 ,用 C、C++ 和 Rust 等编译语言编写,需要编译成依赖于平台的机器代码。使用这些包,轮子不包含源代码(如 C 源文件),而是包含编译的可执行代码(如 Linux 上的 .so 文件或 Windows 上的 DLL)。

一个轮子,通常适用于所有平台和 Python 版本。Python 是一种解释型语言,不需要提前编译,因此轮子像 sdists 一样包含 .py 文件。

轮子的文件名(忽略一些很少使用的功能)如下所示: package_name-version-python_tag-abi_tag-platform_tag.whl 。此命名约定标识滚轮与哪些平台和 Python 版本兼容。例如,名称 pip-23.3.1-py3-none-any.whl 表示:

  • py3) 这个轮子可以安装在 Python 3 的任何实现上,无论是 CPython(使用最广泛的 Python 实现),还是像 PyPy 这样的替代实现;
  • none )它不依赖于 Python 版本;
  • any) 它不依赖于平台。

More Info about wheel to see here.

conda 和 pip 有什么区别?优先用谁啊?

  • pip:从 PyPI 下载 Python 包的“Python 包管理器/安装器”,优先取 wheel(二进制包),没有 wheel 则回退到 source(sdist)并在本机编译。--prefer-binary 会让 pip 更偏好二进制 wheel,避免本地编译。

  • conda:是跨语言的包/环境管理器,以分发已编译的二进制包为主(包括非 Python 的系统库),从 conda 仓库或 channel(例如 conda-forge)取包,通常能避免本机编译 C/C++ 依赖。

两者适合的场景(何时用哪个)

  • 优先用 conda(如果你在用 conda 环境):当包有复杂的 C/C++、外部库依赖(如科学栈、GDAL、ffmpeg、mupdf 等),能在 conda/conda-forge 上找到对应包时,conda 更稳,因为它 提供了已编译的二进制 并且 会处理底层库依赖
  • 用 pip 来补缺:如果某包在 conda 仓库里没有,或者 conda 的版本滞后,用 pip 在已激活的 conda 环境里安装通常可行(先用 conda 安装尽可能多的二进制依赖,再用 pip 安装纯 Python 包)。这也是官方常见建议的混合做法
  • 纯 Python 虚拟环境(venv/virtualenv)下:直接用 pip(PyPI)是最常见做法。对于需要编译的扩展,事先准备好编译器和 dev 库。

安装路径:pip / conda 分别装到哪里(如何查看)

  • pip(在当前 Python 环境中):会 装到该 Python 的 site-packages 中。常见位置(示例):

    • Linux/macOS(系统或自编译 Python):/usr/local/lib/pythonX.Y/site-packages/

    • venv / conda env:$VENV_OR_CONDA_PREFIX/lib/pythonX.Y/site-packages/

    • –user 模式:~/.local/lib/pythonX.Y/site-packages/(可通过 python -m site --user-site 查看)。

    查看某包路径:pip show pymupdf 会输出 Location,或在 Python 里 import pymupdf; print(pymupdf.__file__)

  • conda:用 conda info --envs 可看环境位置

    用 conda 时,先确认 conda-forge 是否有对应包并用该 channel 安装:

    conda search -c conda-forge pymupdf
    conda install -c conda-forge pymupdf
    
  • 在 conda env 中用 pip 安装,先激活 env,再用 pip,

    conda activate myenv
    python -m pip install --upgrade pip setuptools wheel
    python -m pip install pymupdf   # 或加 --prefer-binary