Python 包管理工具 pip 详解

本文最后更新于 2023年4月29日 凌晨

命令行说明:

对于 Windows、Linux、macOS 三大平台,在 Shell 中调用 Python 的命令有非常微小的差异,本文中并未详细区分。一般情况下,Windows 使用 pypython,而 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日
许可协议