长话短说

长话短说

Python 包经常托管在许多发行版的存储库中。看完之后教程,特别是标题为“你真的想这样做吗”的部分,我避免使用 pip 并更喜欢使用系统存储库,只有当我需要安装不在存储库中的包时才诉诸 pip。

但是,由于这是一种不一致的安装方法,因此仅使用 pip 会更好吗?对于在两个地方都可用的软件包,使用 pip 而不是系统自己的存储库有哪些好处/缺点?

我包含的链接状态

始终使用标准 Debian / NeuroDebian 软件包的优点是这些软件包经过仔细测试以确保彼此兼容。 Debian 软件包记录了与其他库的依赖关系,因此您将始终在安装过程中获得所需的库。

我用拱门。除了 apt 之外,其他包管理系统也是这种情况吗?

答案1

我认为使用 Python 模块(无论是系统模块还是用户模块)在系统上安装的最大缺点pip是,发行版的包管理系统不知道它们。这意味着它们不会用于需要它们的任何其他包,并且您可能希望在将来安装它们(或者在升级后可能开始使用其中一个模块);然后,您最终会得到这两个pip模块的发行版管理版本,这可能会导致问题(我遇到了还有一个这样的例子最近)。所以你的问题最终是一个全有或全无的命题:如果你仅有的用于pipPython模块,你不能再使用你的发行版的包管理器来处理任何想要使用Python模块的东西......

您链接到的页面中给出的一般建议非常好:尝试尽可能使用发行版的软件包,仅用于pip未打包的模块,并且当您这样做时,请在用户设置中而不是系统中这样做 -宽的。尽可能使用虚拟环境,特别是对于模块开发。特别是在 Arch 上,您不应该遇到由旧模块引起的问题;即使在这可能成为问题的发行版上,虚拟环境也可以很容易地处理它。

始终值得考虑的是,发行版的库和模块包主要是为了供发行版中的其他包使用而打包的;对于使用这些库和模块进行开发来说,拥有它们是一个很好的副作用,但这不是主要用例。

答案2

长话短说

  • 使用pip(+ virtualenv) 来处理东西(库、框架,也许是开发工具)你的项目(您开发的)使用
  • 使用应用程序的包管理器使用(作为最终用户)

开发依赖

如果您正在使用 Python 开发软件,您将需要使用pip项目的所有依赖项,无论是运行时依赖项、构建时依赖项还是自动化测试和自动合规性检查所需的内容(linter、样式检查器、静态类型检查器) ...)

有几个原因:

  • 这允许您使用虚拟环境(直接或通过virtualenvwrapper或pipenv或其他方式)将不同项目的依赖关系相互分离,并将您“在生产中”(作为用户)使用的Python应用程序与任何可能出现的外来恶作剧(甚至只是不兼容)隔离开来。继续发展。
  • requirements.txt这允许您在(如果您的项目是应用程序)或setup.py(如果您的项目是库或框架)文件中跟踪项目的所有依赖项。这可以与源代码一起检查到修订控制(例如 Git)中,以便您始终知道哪个版本的代码依赖于哪个版本的依赖项。
  • 上述内容使其他开发人员能够在您的项目上进行协作,即使他们不使用相同的 Linux 发行版,甚至不同的操作系统(如果所使用的依赖项也可以在 Mac 和 Windows 或他们碰巧使用的任何设备上使用)
  • 您不希望操作系统的包管理器的自动更新破坏您的代码。您应该更新您的依赖项,但您应该有意识地在您选择的时间进行更新,以便您可以准备好修复代码或回滚更新。 (如果您跟踪修订控制系统中的完整依赖项声明以及代码,这很容易。)

如果您觉得需要分离直接和间接依赖项(或区分依赖项的可接受版本范围和实际使用的版本,请参见“版本固定”),请查看 pip-tools 和/或 pipelinev。这还允许您区分构建和测试依赖关系。 (构建和运行时依赖关系之间的区别可能可以编码在setup.py

您使用的应用程序

对于您用作普通应用程序的东西就这样发生了要使用 Python 编写,请选择操作系统的包管理器。它将确保它保持合理的最新状态并与包管理器安装的其他内容兼容。大多数 Linux 发行版也会声称他们不分发任何恶意软件。

如果您需要的东西在您的发行版的默认软件包存储库中不可用,您可以查看其他软件包存储库(例如基于 deb 的发行版的启动板)或pip无论如何使用。如果是后者,请使用--user安装到用户的家中而不是系统范围内,这样就不太可能破坏 Python 安装。 (对于您只是暂时或很少需要的东西,您甚至可以使用 virtualenv。)

答案3

使用包管理器的另一个原因是更新将自动应用,这对于安全性至关重要。想想如果 Equifax 使用的 beans 包已经通过 yum-cron-security 自动更新,那么黑客攻击可能就不会发生。

在我的个人开发盒上,我使用 Pip,在产品中我使用软件包。

答案4

概括

您正在处理的模块分为三类:

  1. 这些支持程序是为所有使用操作系统软件包系统的用户安装的。 (这甚至可能包括人们使用 Python 编程的工具和库;请参见下文。)对于这些,您可以尽可能使用操作系统软件包,并pip在必要时安装到系统目录。
  2. 特定用户安装的那些支持程序仅供其自己使用,也用于她“日常”使用 Python 作为脚本语言的某些方面。对于她使用的这些pip --user,也许pyenv或者蟒蛇,以及类似的工具和策略。
  3. 支持特定应用程序的开发和使用。对于这些,您可以使用virtualenv(或类似的工具)。

这里的每个级别也可能得到前一个级别的支持。例如,(2) 中的用户可能依赖于通过操作系统包安装的 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或,但下载其自己的副本以引导其正在创建的虚拟环境。pipvirtualenv

也就是说,在某些情况下,提供更多的开发环境可能是完全合理的。您可能将 Python 接口连接到复杂的包(例如 DBMS)中,您希望在其中使用该包的系统版本,并且您认为最好也让系统选择您将用来与之通信的特定 Python 库代码。或者,您可能正在部署大量具有 Python 类基本开发环境的主机,并发现使用标准系统包实现自动化最简单。

用户“日常”程序和套餐

用户可能拥有不太适合虚拟环境的 Python 库或程序,因为他们首先希望帮助创建虚拟环境(例如,虚拟环境包装器)或者它们是您通常从命令行使用的东西,即使在执行非 Python 工作时也是如此。即使他们确实有能力安装这些工具的系统版本,他们也可能会觉得安装自己的工具更舒服(例如,因为他们希望使用该工具及其依赖项的最新版本)。

一般来说pip --user,人们会为此使用它,尽管某些依赖项(例如 Python 解释器本身)需要更多的东西。pyenv蟒蛇对于构建个人解释器(无论是安装为默认解释器还是其他解释器)很有用~/.local/bin,当然,如果开发库可用,人们总是可以从源代码“手动”构建。

我尝试在这里安装最少的东西:virtualenvwrapper(因为我经常使用它),也许还有最新版本的 pip。对于我编写的要在许多主机上使用的个人脚本,我尽量避免依赖于标准库之外或 Python 3。 (不过,随着我将越来越多的个人脚本转移到 Python,我们会看看我能坚持多久。)

独立的应用程序开发和运行时环境

这是通常的 virtualenv 的事情。对于开发,您几乎应该始终使用 virtualenv 来确保您没有使用系统依赖项,或者通常使用多个 virtualenv 来针对不同的 Python 版本进行测试。

这些虚拟环境也适用于具有大量依赖项的应用程序,您希望避免污染用户环境。例如我通常设置一个 virtualenv 来运行朱皮特笔记本之类的。

相关内容