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 组织更新维护。

PyPI

安装pip

从 Python 3.4 起,大部分 Python 发行版已经内置了 pip。可以通过 pip --version 命令快速检查当前机器是否已经安装了 pip:已安装会出现 pip 的版本信息,未安装则会报错。例如:

1
2
$ python3.11 -m pip --version
pip 23.1 from /home/muzing/.local/lib/python3.11/site-packages/pip (python 3.11)

说明此机器已经为 Python 3.11 环境安装了 23.1 版本的 pip 工具,安装位置在用户家目录下的 .local。如果 pip 可用,可以先跳转到本文升级包一节,将 pip 升级到最新版本;如果不可用,则继续按照本节的内容进行安装。

是的,pip 本身也是一个 Python 包,默认安装在 /python/site-packages/pip 目录下,所以可以使用 pip 对 pip 进行升级、可以使用 python -m pip 的语法使用指定的解释器以包的形式调用 pip。

Windows安装包

对于 Windows 平台,最常见、最推荐的 Python 安装方式是从官网下载安装包:

从官网下载适用于Windows的安装包

如果以默认方式安装,则会自动同时安装 pip:

默认方式安装Python

如果使用自定义安装,记得勾选 pip 即可:

自定义安装Python

Linux发行版

对于目前大部分常见 Linux 发行版,往往内置一个 Python3 解释器,但默认没有安装对应的 pip 工具。可以使用这些发行版提供的 Linux 软件包管理工具安装 pip。例如:

1
2
3
# Ubuntu
$ sudo apt update
$ sudo apt install python3-pip
1
2
# Arch Linux
$ sudo pacman -S python-pip

除使用系统内置或软件源提供的 Python 外,有时也会通过从源码编译的方式获得其他版本的 Python,编译安装解释器时会默认一并安装 pip,可以参考在 Ubuntu 22.04 上安装 Python 3.9。

其他安装方式

如果以上方式都不可用,pip文档-安装小节中还提到了两种安装方式:ensurepip 模块与 get-pip.py 脚本。

ensurepip模块

从 Python 3.4 起,Python 标准库中包含了一个名为 ensurepip 的模块,用于引导 pip 安装。使用方式很简单:

1
python -m ensurepip --upgrade

get-pip脚本

  1. 从 https://bootstrap.pypa.io/get-pip.py 下载脚本
  2. 启动一个终端,进入刚才的下载位置,使用 Python 解释器执行 get-pip.py 脚本
1
python get-pip.py

关于此脚本的更多信息,参考 pypa/get-pip 项目的 README。

常用命令与基本使用

安装包

使用 pip 在环境中安装 Python 包,只需使用 pip install 命令。最简单的默认安装:

1
python -m pip install sampleproject

此方式会从 PyPI 下载安装该包的最新版本,如果想安装包的指定版本,可以使用如下方式:

1
2
3
python -m pip install "sampleproject==1.4"  # 安装1.4版本的sampleproject
python -m pip install "sampleproject>=1.4,<2" # 安装版本号大于等于1.4同时小于2的
python -m pip install "sampleproject~=1.4.2" # 安装与1.4.2兼容的版本

关于版本约束的语法,见本文版本约束符小节。

安装来自于 GitHub 的包:

1
python -m pip install git+https://github.com/pypa/sampleproject.git@main

从分发文件(源码形式或 wheel 形式)安装包:

1
2
python -m pip install sampleproject-1.0.tar.gz  # 从源码分发包文件安装
python -m pip install sampleproject-1.0-py3-none-any.whl # 从wheel分发文件安装

关于 wheel 的话题,还会在下文中展开讨论。

升级包

在 install 命令后加上 --upgrade 参数,即可将指定的包升级至最新版本:

1
python -m pip install --upgrade sampleproject

如上文所述,pip 本身也是一个 Python 包,也可以用这种方式升级:

1
2
# 同时升级 pip、setuptools、wheel 到最新版本
python -m pip install --upgrade pip setuptools wheel

卸载包

在卸载包之前,请先运行 pip show 命令检查该包的依赖关系:

1
python -m pip show [package-name]  # 检查 [package name] 的信息

例如:

1
2
3
4
5
6
7
8
9
10
11
$ pip show black
Name: black
Version: 23.1.0
Summary: The uncompromising code formatter.
Home-page:
Author:
Author-email: Łukasz Langa <lukasz@langa.pl>
License: MIT
Location: D:\Python\Python311\Lib\site-packages
Requires: click, mypy-extensions, packaging, pathspec, platformdirs
Required-by:

注意最后的两个字段 Requires 和 Required-by 。可以看到,在此机器上 Black 包依赖于 click、mypy-extensions 等五个包,如果卸载它们中的任何一个,则 Black 也就不能正常使用了。没有任何包依赖于 Black,因此直接卸载 Black 是安全的。

使用 uninstall 命令即可卸载包:

1
python -m pip uninstall [package-name]

注意,此操作仅卸载指定的包,而不会卸载安装此包时为其自动安装的依赖项包。例如 pip uninstall black 只会卸载 black,而不会卸载 click、mypy-extensions 等依赖包。

卸载包时会显示要删除的文件,并要求确认。如果已经在上一步中检查确认了该包是可以删除的(没有被其他包依赖),那么可以加上一个 -y 选项来跳过显示文件列表和确认:

1
python -m pip uninstall [package-name] -y

也可以在一行命令中卸载多个包,包名之间用空格隔开即可:

1
python -m pip uninstall [package-name-1] [package-name-1] [package-name-1]

还可以通过 -r <requirments file> 选项来卸载 requirements 中列出的所有包,当检查确认不会破坏其他依赖关系后,运行下面的命令:

1
python -m pip uninstall -r requirements.txt -y

列出包

若想查看当前 Python 环境中都安装了哪些包、包的版本如何,可以使用 pip list 命令:

1
2
3
4
5
6
$ python -m pip list                       
Package Version
---------- -------
pip 23.1.1
setuptools 67.7.1
wheel 0.40.0

添加 --outdated 即可列出所有可更新的包及其版本信息:

1
2
3
4
5
6
7
8
$ python -m pip list --outdated
Package Version Latest Type
---------- ------- ------ -----
pip 22.3.1 23.1.1 wheel
setuptools 65.5.0 67.7.2 wheel

[notice] A new release of pip available: 22.3.1 -> 23.1.1
[notice] To update, run: pip install --upgrade pip

搜索包

历史上,可以使用 pip search 命令在终端中搜索查看包的简要信息。而如今 PyPI 已经不再支持这种鸡肋的方式,而只推荐在浏览器中打开 PyPI 网页搜索与查看包的详细信息。

PyPI网站上的requests项目首页

使用镜像

对于绝大多数简体中文用户(中国大陆),与默认 PyPI 服务器(https://pypi.org/simple)间的网络通信十分困难,传输速度慢、延时高、丢包率高,下载文件较大的包耗时极长,且连接容易超时断开。幸运的是,国内的一些组织(以高校和互联网公司为主)义务性提供了免费的 PyPI 镜像(mirror)服务:将 PyPI 的所有数据实时同步复制到位于国内的服务器上。故可以修改 pip 配置,令其使用网络距离最近的 PyPI 镜像源,大幅提高安装包的速度与成功率。

以清华大学开源软件镜像站为例,简单演示如何使用 PyPI 镜像:

1
2
python -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package  # 单次临时使用
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple # 写入本地配置文件,永久生效

pip 命令行中的 -i/--index-url 参数用于指定使用的 PyPI 索引源。使用上面的 pip config 命令后,会在用户家目录中创建(或修改原有的)pip 配置文件,形如

1
2
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple

pip 每次运行时都会读取其中的配置并应用生效。关于该配置文件的更多信息,参见 pip - Configuration。

Requirements需求文件

需求文件简介

许多 Python 开源项目都在根目录存有一个名为 requirements.txt 的文本文件。这类文件被称为需求文件(Requirements Files),详细描述了此项目而需要依赖于哪些 Python 包。例如:

1
2
3
4
# requirements.txt
numpy==1.24.2
scipy==1.10.1
matplotlib==3.7.0

需求文件的文件名并没有语法上的强制要求,但除非有十分特殊的理由,否则都应约定俗成地使用 requirements.txt(大小写敏感)。

使用需求文件

如果某个项目中已经包含了 requirements.txt 文件,那么可以使用如下命令同时安装需求文件中指定的所有包:

1
python -m pip install -r requirements.txt

导出需求文件

在编写自己的 Python 项目时,如果想要创建需求文件,可以使用下面的命令:

1
python -m pip freeze > requirements.txt

pip freeze 命令的作用是按需求文件的语法输出当前 Python 环境中的所有第三方包及其版本,使用 > 将其输出重定向至需求文件中。直接使用 pip freeze 命令的缺点是,会把当前 Python 环境中所有已安装的包都列出来,而不管这些包是否真的被 import 导入使用。为解决此问题,可以使用 pipreqs 等工具来生成 requirements:

1
2
python -m pip install pipreqs # 安装 pipreqs
pipreqs <Project_Dic> --encoding=utf-8 # 生成 requirements,将 <Project_Dic> 替换为你的项目路径

关于 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

wheel - Document

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
2
3
4
# requirements.txt
numpy~=1.24.2
scipy~=1.10.0
matplotlib>=3.7.0, <4

再使用 pip 安装或升级包时,就会按照此要求安装指定范围内的最新版本。

开发环境与生产环境

由于生产环境和开发环境的不同,对有些包的需求也不同。开发环境中往往安装了更多用于测试等功能的辅助性包,这些包在生产环境中是不需要的。我们可以通过在需求文件中嵌套需求文件的方法来解决这个问题:

创建第二个 requirements 文件(requirements_dev.txt)来列出创建开发环境所需要的其他工具,例如:

1
2
3
# In requirements_dev.txt
-r requirements.txt
pytest>=4.2.0

由于 pip 允许在 requirements 文件中指定其他参数,所以可以在其中加上一行 -r requirements.txt。

这时直接使用

1
python -m pip install -r requirements_dev.txt

就可以安装所有开发环境所需要的包了。

而此时在生产环境继续使用命令:

1
python -m pip install -r requirements.txt

就不会安装 pytest ,保持了生产环境的轻量可靠。

依赖库管理工具

继任者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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
$ pip help

Usage:
pip3 <command> [options]

Commands:
install 安装包
download 下载包(只下载不安装)
uninstall 卸载包
freeze 以 requirements 格式列出所有依赖包
list 列出所有已安装的包
show 显示已安装包的信息
check 验证已安装的包是否具有兼容的依赖项
config 管理本地和全局配置
search 在 PyPI 中搜索包
cache 检查和管理 pip 的 wheel 缓存
index 检索包索引中的可用信息
wheel 为你的 requirements 构建 wheel
hash 计算包档案的 hash 值
completion 用于补全命令的辅助命令
debug 显示对 debug 有帮助的信息
help 显示命令的帮助

General Options:
-h, --help 显示帮助

--debug 让未处理的异常传播到主子程序之外,而不是记录它们

--isolated 以隔离模式运行 pip ,忽略环境变量和用户配置

--require-virtualenv 只有在虚拟环境中才能运行 pip,否则报错退出

--python <python> 使用指定的 Python 解释器运行 pip

-v, --verbose 显示更多的输出。此选项可累加,且最多3次

-V, --version 显示版本并退出

-q, --quiet 显示更少的输出。 此选项可累加,且最多三次 (对应于 WARNING,
ERROR, 和 CRITICAL 三种日志等级)

--log <path> 附加详细日志的路径

--no-input 禁用提示输入

--keyring-provider <keyring_provider>
如果允许用户输入,则通过 keyring 库启用凭证查询。指定使用
[disabled, import, subprocess] 中的哪种机制(默认为disabled)

--proxy <proxy> 使用该形式指定代理:
[user:passwd@]proxy.server:port

--retries <retries> 每个连接尝试重新连接的最大次数(默认为5次)

--timeout <sec> 设置 socket 超时时间(默认15秒)

--exists-action <action> 路径已存在时的默认操作:
(s)witch, (i)gnore, (w)ipe, (b)ackup, (a)bort

--trusted-host <hostname> 标记此 host 或 host:port 为受信任的,
即使它没有有效的HTTPS, 甚至没有 HTTPS

--cert <path> PEM-encoded CA certificate bundle 的路径
如果提供了该项,则覆盖默认值
查看 pip 文档中的 'SSL Certificate Verification'
以查看更多信息

--client-cert <path> SSL 客户端证书的路径,
一个单独的包含私钥和 PEM 格式证书的单个文件

--cache-dir <dir> 将缓存数据存储在 <dir> 中

--no-cache-dir 禁用缓存

--disable-pip-version-check 不要定期检查 PyPI 以确认是否有新版本 pip 可下载。
使用 --no-index 关闭提示

--no-color 关闭彩色输出

--no-python-version-warning 关闭 即将不受支持的 Python 的警告

--use-feature <feature> 启用可能向后不兼容的新功能

--use-deprecated <feature> 启用将在未来被移除的已弃用功能

更多详细信息,参见 pip-Commands。

参考文档


Python 包管理工具 pip 详解
https://muzing.top/posts/594ac4a6/
作者
Muzing
发布于
2023年4月20日
更新于
2023年4月29日
许可协议