Python 包经常托管在许多发行版的存储库中。阅读本教程后,特别是标题为“你真的想这样做”的部分后,我避免使用 pip,而是更喜欢使用系统存储库,只有当我需要安装不在存储库中的包时才使用 pip。
但是,因为这是一种不一致的安装方式,所以只使用pip会更好吗?对于在两个地方都可用的软件包,在系统自己的存储库上使用 pip 有什么好处/反对者?
我包含的链接状态
始终使用标准 Debian / NeuroDebian 软件包的优势在于,这些软件包都经过仔细测试以相互兼容。Debian 软件包记录了与其他库的依赖关系,因此您将始终获得所需的库作为安装的一部分。
我用拱门。除了 apt 之外的其他包管理系统是否也是这种情况?
我看到
pip
在您的系统上安装 Python 模块(无论是作为系统模块还是作为用户模块)的最大缺点是您的发行版的包管理系统不会知道它们。这意味着它们不会用于任何其他需要它们的软件包,以及您将来可能想要安装的软件包(或者可能在升级后开始使用其中一个模块);然后,您将获得模块的 - 和分发管理版本,这可能会导致问题(我最近pip
遇到了另一个实例)。所以你的问题最终是一个全有或全无的命题:如果你只使用pip
对于 Python 模块,您不能再将发行版的包管理器用于任何想要使用 Python 模块的东西......您链接到的页面中给出的一般建议非常好:尝试尽可能使用您的发行版包,仅
pip
用于未打包的模块,并且当您这样做时,请在您的用户设置中而不是系统中这样做 -宽的。尽可能使用虚拟环境,特别是模块开发。尤其是在 Arch 上,您不应该遇到由旧模块引起的问题;即使在可能成为问题的发行版上,虚拟环境也很容易处理它。始终值得考虑的是,发行版的库和模块包主要是为了使用发行版中的其他包而打包的;将它们放在身边是使用这些库和模块进行开发的一个很好的副作用,但这不是主要用例。
TL;博士
pip
(+ virtualenv) 用于您的项目(您开发的)使用的东西(库、框架,也许是开发工具)开发依赖
如果您正在使用 Python 开发软件,您将希望使用
pip
项目的所有依赖项,无论是运行时依赖项、构建时依赖项还是自动化测试和自动化合规性检查所需的东西(linter、样式检查器、静态类型检查器) ...)有几个原因:
requirements.txt
(如果您的项目是应用程序)或setup.py
(如果您的项目是库或框架)文件中跟踪项目的所有依赖项。这可以与源代码一起检查到修订控制(例如 Git)中,以便您始终知道哪个版本的代码依赖于您的依赖项的哪个版本。如果您觉得需要分离直接和间接依赖项(或区分依赖项的可接受版本范围和使用的实际版本,请参阅“版本固定”)查看 pip-tools 和/或 pipenv。这也将允许您区分构建和测试依赖项。(构建和运行时依赖项之间的区别可能可以编码为
setup.py
)您使用的应用程序
对于您用作普通应用程序并且恰好是用 Python 编写的东西,更喜欢您的操作系统的包管理器。它将确保它保持合理的最新状态并与包管理器安装的其他东西兼容。大多数 Linux 发行版还会声称它们不会分发任何恶意软件。
如果您的发行版的默认软件包存储库中没有您需要的东西,您可以查看其他软件包存储库(例如基于 deb 的发行版的启动板)或
pip
无论如何使用。如果是后者,请使用--user
安装到用户家中而不是系统范围内,这样您就不太可能破坏 Python 安装。(对于你只需要临时或很少需要的东西,你甚至可以使用 virtualenv。)使用包管理器的另一个原因是更新将自动应用,这对安全性至关重要。想想如果 Equifax 使用的 beans 包已经通过 yum-cron-security 自动更新,黑客可能不会发生。
在我的个人开发盒中,我使用 Pip,在产品中我使用包。
如果我们正在讨论安装 python 包以在您编写的代码中使用,请使用 pip。
对于您正在处理的每个项目,创建一个虚拟环境,然后只使用 pip 安装该项目需要的东西。这样,您以一致的方式安装您使用的所有库,并且它们被包含在内并且不会干扰您通过包管理器安装的任何内容。
如果你打算发布任何 python 代码,通常你会在你的项目中添加一个
setup.py
或requirements.txt
,这将允许 pip 自动获取它的所有依赖项。允许您轻松地为该项目创建或重新创建虚拟环境。概括
您正在处理的模块分为三类:
pip
在必要时安装到系统目录。pip --user
pyenv或pythonz以及类似的工具和策略。virtualenv
(或类似的工具)。这里的每个级别也可能从前一个级别获得支持。例如,我们在 (2) 中的用户可能依赖于通过 OS 包安装的 Python 解释器。
更详细地介绍一下:
系统程序和软件包
用 Python 编写的你想“直接运行”的程序很简单:只需使用操作系统安装工具,让它们带入任何需要的东西;这与非 Python 程序没有什么不同。这可能会引入您机器上的用户可能开始依赖的 Python 工具/库(例如 Python 解释器本身!);只要他们了解依赖关系,并且理想情况下,知道在不提供这些依赖关系的主机上处理它的替代方法,这不是问题。
这种依赖关系的一个常见且简单的示例是我的一些
~/.local/bin/
以#!/usr/bin/env python
. 这些将在 RH/CentOS 7 和大多数(但不是全部)Ubuntu 安装上正常工作(只要它们在 Python 2 下运行);他们不会在基本的 Debian 安装或 Windows 上。尽管我不喜欢我的个人环境在很大程度上依赖于操作系统包(我在许多不同的操作系统上工作),但我觉得这样的事情是可以接受的;我在没有系统 Python 且无法获得系统 Python 的罕见主机上的备份计划是使用如下所述的用户系统。使用系统 python 解释器的人通常也依赖于系统
pip3
。这就是我通常在系统依赖项上画线的地方;一切从前virtualenv
我处理自己。(例如,我的标准激活脚本依赖于路径中的任何pip3
内容pip
,但会下载自己的副本virtualenv
以引导它正在创建的虚拟环境。也就是说,在某些情况下,提供更多的开发环境是完全合理的。您可能将 Python 接口连接到复杂的包(例如 DBMS)中,您希望在其中使用它的系统版本,并且您觉得最好也让系统选择您将用来与之对话的特定 Python 库代码。或者,您可能正在部署许多具有 Python 类的基本开发环境的主机,并且发现使用标准系统包实现自动化是最容易的。
用户“日常”程序和包
用户可能拥有不适合虚拟环境的 Python 库或程序,因为他们首先希望帮助创建虚拟环境(例如virtualenvwrapper),或者它们是您通常在命令行中使用的东西,即使在做非 Python 工作。即使他们确实有能力安装这些系统版本,他们可能会觉得安装自己的系统版本更舒服(例如,因为他们想使用最新版本的工具及其依赖项)。
通常
pip --user
是人们将为此使用的,尽管某些依赖项,例如 Python 解释器本身,需要的远不止这些。pyenv和pythonz可用于构建个人解释器(无论是否安装~/.local/bin
为默认解释器),当然,如果开发库可用,则始终可以从源代码“手动”构建。我尝试在这里安装最少的东西:virtualenvwrapper(因为我经常使用它),也许是最新版本的 pip。我尽量避免依赖标准库或 Python 3 之外的我编写的个人脚本,以便在许多主机上使用。(虽然我们会看到随着我将越来越多的这些个人脚本转移到 Python 中,我能坚持多久。)
独立的应用程序开发和运行时环境
这是通常的 virtualenv 事情。对于开发,您应该几乎总是使用 virtualenv 来确保您不使用系统依赖项,或者经常使用多个依赖项来针对不同的 Python 版本进行测试。
这些虚拟环境也适用于您希望避免污染用户环境的具有大量依赖项的应用程序。例如,我通常设置一个 virtualenv 来运行Jupyter笔记本等。