Python 包管理工具 pip 详解
本文最后更新于 2023年4月29日 凌晨
命令行说明:
对于 Windows、Linux、macOS 三大平台,在 Shell 中调用 Python 的命令有非常微小的差异,本文中并未详细区分。一般情况下,Windows 使用 py
或 python
,而 Linux 使用 python3
,简单替换即可。
简介
pip 是一个 Python 的包(Package)管理工具,用于从 PyPI 安装和管理 Python 标准库之外的其他包(第三方包)。从 Python 3.4 起,pip 已经成为 Python 安装程序的一部分,也是官方标准的 Python 包管理器,由 PyPA 组织更新维护。
安装pip
从 Python 3.4 起,大部分 Python 发行版已经内置了 pip。可以通过 pip --version
命令快速检查当前机器是否已经安装了 pip:已安装会出现 pip 的版本信息,未安装则会报错。例如:
1 |
|
说明此机器已经为 Python 3.11 环境安装了 23.1 版本的 pip 工具,安装位置在用户家目录下的 .local。如果 pip 可用,可以先跳转到本文升级包一节,将 pip 升级到最新版本;如果不可用,则继续按照本节的内容进行安装。
是的,pip 本身也是一个 Python 包,默认安装在 /python/site-packages/pip
目录下,所以可以使用 pip 对 pip 进行升级、可以使用 python -m pip
的语法使用指定的解释器以包的形式调用 pip。
Windows安装包
对于 Windows 平台,最常见、最推荐的 Python 安装方式是从官网下载安装包:
如果以默认方式安装,则会自动同时安装 pip:
如果使用自定义安装,记得勾选 pip 即可:
Linux发行版
对于目前大部分常见 Linux 发行版,往往内置一个 Python3 解释器,但默认没有安装对应的 pip 工具。可以使用这些发行版提供的 Linux 软件包管理工具安装 pip。例如:
1 |
|
1 |
|
除使用系统内置或软件源提供的 Python 外,有时也会通过从源码编译的方式获得其他版本的 Python,编译安装解释器时会默认一并安装 pip,可以参考在 Ubuntu 22.04 上安装 Python 3.9。
其他安装方式
如果以上方式都不可用,pip文档-安装小节中还提到了两种安装方式:ensurepip
模块与 get-pip.py
脚本。
ensurepip模块
从 Python 3.4 起,Python 标准库中包含了一个名为 ensurepip
的模块,用于引导 pip 安装。使用方式很简单:
1 |
|
get-pip脚本
- 从 https://bootstrap.pypa.io/get-pip.py 下载脚本
- 启动一个终端,进入刚才的下载位置,使用 Python 解释器执行 get-pip.py 脚本
1 |
|
关于此脚本的更多信息,参考 pypa/get-pip 项目的 README。
常用命令与基本使用
安装包
使用 pip 在环境中安装 Python 包,只需使用 pip install
命令。最简单的默认安装:
1 |
|
此方式会从 PyPI 下载安装该包的最新版本,如果想安装包的指定版本,可以使用如下方式:
1 |
|
关于版本约束的语法,见本文版本约束符小节。
安装来自于 GitHub 的包:
1 |
|
从分发文件(源码形式或 wheel 形式)安装包:
1 |
|
关于 wheel 的话题,还会在下文中展开讨论。
升级包
在 install
命令后加上 --upgrade
参数,即可将指定的包升级至最新版本:
1 |
|
如上文所述,pip 本身也是一个 Python 包,也可以用这种方式升级:
1 |
|
卸载包
在卸载包之前,请先运行 pip show
命令检查该包的依赖关系:
1 |
|
例如:
1 |
|
注意最后的两个字段 Requires 和 Required-by 。可以看到,在此机器上 Black 包依赖于 click、mypy-extensions 等五个包,如果卸载它们中的任何一个,则 Black 也就不能正常使用了。没有任何包依赖于 Black,因此直接卸载 Black 是安全的。
使用 uninstall
命令即可卸载包:
1 |
|
注意,此操作仅卸载指定的包,而不会卸载安装此包时为其自动安装的依赖项包。例如 pip uninstall black
只会卸载 black,而不会卸载 click、mypy-extensions 等依赖包。
卸载包时会显示要删除的文件,并要求确认。如果已经在上一步中检查确认了该包是可以删除的(没有被其他包依赖),那么可以加上一个 -y
选项来跳过显示文件列表和确认:
1 |
|
也可以在一行命令中卸载多个包,包名之间用空格隔开即可:
1 |
|
还可以通过 -r <requirments file>
选项来卸载 requirements 中列出的所有包,当检查确认不会破坏其他依赖关系后,运行下面的命令:
1 |
|
列出包
若想查看当前 Python 环境中都安装了哪些包、包的版本如何,可以使用 pip list
命令:
1 |
|
添加 --outdated
即可列出所有可更新的包及其版本信息:
1 |
|
搜索包
历史上,可以使用 pip search
命令在终端中搜索查看包的简要信息。而如今 PyPI 已经不再支持这种鸡肋的方式,而只推荐在浏览器中打开 PyPI 网页搜索与查看包的详细信息。
使用镜像
对于绝大多数简体中文用户(中国大陆),与默认 PyPI 服务器(https://pypi.org/simple)间的网络通信十分困难,传输速度慢、延时高、丢包率高,下载文件较大的包耗时极长,且连接容易超时断开。幸运的是,国内的一些组织(以高校和互联网公司为主)义务性提供了免费的 PyPI 镜像(mirror)服务:将 PyPI 的所有数据实时同步复制到位于国内的服务器上。故可以修改 pip 配置,令其使用网络距离最近的 PyPI 镜像源,大幅提高安装包的速度与成功率。
以清华大学开源软件镜像站为例,简单演示如何使用 PyPI 镜像:
1 |
|
pip 命令行中的 -i
/--index-url
参数用于指定使用的 PyPI 索引源。使用上面的 pip config
命令后,会在用户家目录中创建(或修改原有的)pip 配置文件,形如
1 |
|
pip 每次运行时都会读取其中的配置并应用生效。关于该配置文件的更多信息,参见 pip - Configuration。
Requirements需求文件
需求文件简介
许多 Python 开源项目都在根目录存有一个名为 requirements.txt
的文本文件。这类文件被称为需求文件(Requirements Files),详细描述了此项目而需要依赖于哪些 Python 包。例如:
1 |
|
需求文件的文件名并没有语法上的强制要求,但除非有十分特殊的理由,否则都应约定俗成地使用 requirements.txt
(大小写敏感)。
使用需求文件
如果某个项目中已经包含了 requirements.txt
文件,那么可以使用如下命令同时安装需求文件中指定的所有包:
1 |
|
导出需求文件
在编写自己的 Python 项目时,如果想要创建需求文件,可以使用下面的命令:
1 |
|
pip freeze
命令的作用是按需求文件的语法输出当前 Python 环境中的所有第三方包及其版本,使用 >
将其输出重定向至需求文件中。直接使用 pip freeze
命令的缺点是,会把当前 Python 环境中所有已安装的包都列出来,而不管这些包是否真的被 import 导入使用。为解决此问题,可以使用 pipreqs 等工具来生成 requirements:
1 |
|
关于 requirements.txt
还有许多值得讨论的话题。出于篇幅排布之考虑,将此小节放在本文进阶话题之下,感兴趣的读者可以跳转阅读。
进阶话题
关于 pip 还有许多话题值得深入讨论,时间紧迫的初学者可以先略过下面的部分。但这些话题十分有趣,也有助于减少日后配置开发环境遇到错综复杂扑朔迷离的问题(相信我,出现这种问题的几率比想象中高得多)时完全不知所措的情况。
使用指定环境中的pip
python -m pip
pip --python <python>
版本约束符
符号 | 描述 | 举例 |
---|---|---|
> |
任何大于指定版本的版本 | >3.1 : 3.2.0 3.2.5 3.5.2 … |
< |
任何小于指定版本的版本 | <3.1 : 3.0.5 2.7.3 … |
<= |
小于等于指定版本的版本 | <=3.1 : 3.1 3.0 … |
>= |
大于等于指定版本的版本 | >=3.1 : 3.1 3.2 … |
== |
完全指定版本 | ==3.1 : 仅 3.1 版本 |
!= |
除指定版本外的其他版本 | !=3.1 : 除 3.1 版本 |
~= |
兼容的版本 | ~=3.1.2 : >=3.1.2, ==3.1.* ; ~=3.1 : >=3.1, ==3.* |
* |
可以用在版本号的末尾,代表所有 | ==3.1.* : 所有以 3.1 起始的版本,3.1.0 3.1.1 3.1.2 … |
关于版本标识符和支持的比较运算符的详细信息,参见 PEP 440。
wheel
PEP 427 - The Wheel Binary Package Format 1.0
再探Requirements
需求文件语法
https://pip.pypa.io/en/stable/reference/requirements-file-format/
微调需求
有时我们并不需要指定第三方包的版本严格等于(hardcoding)目前使用的版本
一般来讲,包都是向后兼容的,且新版本的包往往有修复 bug 、提升性能、提供新功能等优化,故倾向于安装更新版本的包。但对于另一些情况,太新版本的包反而可能会出现问题:如对旧版本不兼容的更改(可能出现在大版本号更新时,类似于 Python3 语法不兼容 Python2 的现象)、破坏包之间的依赖关系等。
可以在需求文件中使用版本约束符,更灵活地控制包的版本。例如,在编辑器中打开 requirements.txt
文件,进行如下修改:
1 |
|
再使用 pip 安装或升级包时,就会按照此要求安装指定范围内的最新版本。
开发环境与生产环境
由于生产环境和开发环境的不同,对有些包的需求也不同。开发环境中往往安装了更多用于测试等功能的辅助性包,这些包在生产环境中是不需要的。我们可以通过在需求文件中嵌套需求文件的方法来解决这个问题:
创建第二个 requirements 文件(requirements_dev.txt)来列出创建开发环境所需要的其他工具,例如:
1 |
|
由于 pip 允许在 requirements 文件中指定其他参数,所以可以在其中加上一行 -r requirements.txt
。
这时直接使用
1 |
|
就可以安装所有开发环境所需要的包了。
而此时在生产环境继续使用命令:
1 |
|
就不会安装 pytest ,保持了生产环境的轻量可靠。
依赖库管理工具
- https://github.com/bndr/pipreqs
- https://github.com/jazzband/pip-tools
- https://github.com/damnever/pigar
- https://github.com/naiquevin/pipdeptree
继任者pyproject.toml
requirements.txt
存在一些问题,随着 Python 生态的发展,目前正在逐步被 pyproject.toml
取代。
命令行自动补全
https://pip.pypa.io/en/stable/user_guide/#command-completion
缓存
虽然缓存(Caching)机制在绝大多数时候非常便利——无需反复从网络下载完全相同的数据而直接使用本地缓存,节省了时间与流量;但在极少数情况下,损坏或不完整的本地缓存会带来很大的麻烦。本小节将简要介绍 pip 的缓存机制和管理本地缓存文件的方法。
关于 pip 缓存的更多内容,参见 pip-Caching。
pip 缓存内容
pip 默认启用缓存机制,目前的版本中主要缓存两类内容:HTTP 相应、本地构建的 wheel 文件。
网络
- SSL
- 代理
附录a:pip命令行
此处列出了命令行 pip help
返回的帮助信息,并翻译为中文。
使用 pip help <command>
命令查看某个命令的具体帮助。
1 |
|
更多详细信息,参见 pip-Commands。