Python 管理 —— 包管理

老规矩,在文章开始之前先简单罗列一下基本环境:

  • 操作系统(OS):Ventura 13.4
  • Python 版本:3.11.3
  • pip 版本:23.1.2

Pyhton 的强大来源于其丰富的第三方库,自然在使用 Python 的时候不可避免的会需要用到一些第三方库,那么,如何高效地对这些第三方库进行查找、安装和卸载等等操作,都是包管理涉及的内容。

pip 是官方提供给的一个 Python 包管理工具1,pip 提供了对 Python 包进行的查找、下载、安装以及卸载等功能。下面要介绍的 Python 包管理的内容,也是围绕着 pip 工具展开的。

pip 的安装

注意:一般情况下,如果是从官网 Python.org 下载的 Python 会默认安装 pip.

利用 Python 下载时自带的 ensurepip 模块,可以对 pip 进行安装:

1
python -m ensurepip --upgrade
  • python:Python 的解释器,默认使用的解释器是 CPython,用 >>> 作为提示符2

  • -m ensurepip:在 sys.path 下搜索 ensurepip 的模块,并把相应的 .py 文件作为脚本运行,--upgrade 作为 ensurepip 的模块的参数

    • sys.path:模块的搜索路径,可以通过在 Python 的交互环境中 import sys,将 sys.path 打印出来3

      1
      2
      3
      >>> import sys
      >>> sys.path
      ['', '/usr/local/Cellar/python@3.11/3.11.3/Frameworks/Python.framework/Versions/3.11/lib/python311.zip', '/usr/local/Cellar/python@3.11/3.11.3/Frameworks/Python.framework/Versions/3.11/lib/python3.11', '/usr/local/Cellar/python@3.11/3.11.3/Frameworks/Python.framework/Versions/3.11/lib/python3.11/lib-dynload', '/usr/local/lib/python3.11/site-packages']

可以简单看一下 ensurepip 模块的内容,发现 ensurepip 模块其实是一个文件夹:

1
cd /usr/local/Cellar/python@3.11/3.11.3/Frameworks/Python.framework/Versions/3.11/lib/python3.11/ && ls -l | grep -i ensurepip
1
drwxr-xr-x    7 borne  admin     224  4 22 20:16 ensurepip

通过 tree 命令查看 ensurepip 文件目录:

1
tree ensurepip
1
2
3
4
5
6
7
8
9
10
ensurepip
├── __init__.py
├── __main__.py
├── __pycache__
│   ├── __init__.cpython-311.pyc
│   └── __main__.cpython-311.pyc
├── _bundled
│   ├── pip-23.0.1-py3-none-any.whl
│   └── setuptools-67.6.1-py3-none-any.whl
└── _uninstall.py

进一步发现,由于 __init__.py 标识文件的存在,ensurepip 其实更确切的说是一个包(Package)。

通过 cat 命令,查看一下 __init__.py 文件:

1
cat ensurepip/__init__.py | more

其中,有这样一段代码:

1
2
3
4
5
6
7
parser = argparse.ArgumentParser(prog="python -m ensurepip")
parser.add_argument(
"-U", "--upgrade",
action="store_true",
default=False,
help="Upgrade pip and dependencies, even if already installed.",
)

这就解释了,为什么可以通过 python -m ensurepip --upgrade 安装 pip.

关于 pip 的安装,还有最后一点需要强调的是,一个版本的 Python 对应了一个 pip 工具,理解这一点,对于电脑中存在多个版本的 Python 时尤其的重要,每个 Python 都有自己的 pip 工具,所以,当在使用 pip 工具安装第三方库时,一定要清楚,你当时使用的 pip 属于哪个版本的 Python(这个问题本质上是电脑的环境变量的配置问题),其实这也侧面体现出后面要介绍的 Python 版本管理 和 环境管理的意义和重要性。

如果不清楚当前的 pip 命令属于哪个版本的 Python,可以用 whichwhereis 命令,再结合 ls -l 命令简单查询一下:

1
which pip3
1
/usr/local/bin/pip3
1
ls -l /usr/local/bin/pip3
1
lrwxr-xr-x  1 borne  admin  37  4 22 20:16 /usr/local/bin/pip3 -> ../Cellar/python@3.11/3.11.3/bin/pip3

从上面的结果可以看出,这里的 pip3 对应的是 python@3.11,所以,通过 pip3 安装的第三方库,其实是安装到了 python@3.11site-packages 下。

pip 基本语法

1
python -m pip <pip arguments>
  • python -m pip:使用你指定为 python 的 Python 解释器去执行 pip

提示:也可以直接运行 pip <pip arguments>,但是,还是前面说的那个问题,在运行时要清楚这个 pip 属于谁,当然 python -m pip 也存在同样的问题,运行时也同样要清楚 python 属于哪个版本。

pip 常用的命令

pip 自更新

1
python -m pip install --upgrade pip

pip 安装 Packages

第一种安装方式,也是最常见的情况,使用 Requirement Specifiers4PyPI 安装:

1
2
3
python -m pip install SomePackage            # latest version
python -m pip install SomePackage==1.0.4 # specific version
python -m pip install 'SomePackage>=1.0.4' # minimum version

第二种安装方式,在项目中常用,使用 requirements 文件5进行安装:

1
python -m pip install -r requirements.txt

requirements 文件常常配合着 pip freeze 命令进行使用,将 pip freeze 的结果保存到 requirements 文件中:

1
python -m pip freeze > requirements.txt

第三种安装方式,通过 wheel 进行安装6

1
python -m pip install SomePackage-1.0-py2.py3-none-any.whl

其实,如果阅读得仔细的话,到这也许就会意识到,前面在对 pip 进行安装时,用到的 ensurepip 包内其实有 pip-23.0.1-py3-none-any.whl

pip 卸载 Packages

1
python -m pip uninstall SomePackage

注意:pip 还会在升级到新版本之前自动卸载旧版本的包

pip 列出 Packages

列出已安装的包:

1
python -m pip list

列出过时的包,并显示可用的最新版本:

1
python -m pip list --outdated

显示有关已安装包的详细信息:

1
python -m pip show sphinx

pip 搜索 Packages

pip 可以使用 pip search 命令在 PyPI 中搜索包:

1
python -m pip search "query"

Notes:PyPI no longer supports 'pip search' (or XML-RPC search). Please use https://pypi.org/search (via a browser) instead.

pip 其它的命令

pip 命令补全

pip 支持 bash、zsh 和 fish 中的命令行补全。

为 bash 设置命令行补全:

1
python -m pip completion --bash >> ~/.profile

为 zsh 设置设置命令行补全:

1
python -m pip completion --zsh >> ~/.zprofile

pip freeze

以需求格式输出已安装的包,包以不区分大小写的排序顺序列出。

1
python -m pip freeze
1
2
3
4
5
docutils==0.11
Jinja2==2.7.2
MarkupSafe==0.19
Pygments==1.6
Sphinx==1.2.2

pip 配置

pip 允许用户通过 3 种机制更改其行为7

  • command line options 命令行选项(利用 pip config 命令)
  • environment variables 环境变量
  • configuration files 配置文件

可以对 pip 进行一些个性化的设置,比如:当下载第三库速度太慢时,可以通过设置镜像源加快下载速度。

下面将主要介绍两个比较常用的更改方式:命令行选项和配置文件。

pip config

命令行选项覆盖环境变量,环境变量覆盖配置文件中的值。即:通过命令行选项进行设置的优先级最高。

列出配置文件及其下定义的值:

1
python -m pip config debug

查询某一个具体的配置:

1
python -m pip config get command.option

设置/重置某一个具体的配置:

1
python -m pip config [<file-option>] set/unset command.option value

具体实例:

通过命令行选项设置镜像源

1
python -m pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

通过命令行选项设置 pip 日志

1
python -m pip config set global.log /var/log/pip.log

pip 配置文件

配置文件可以更改命令行选项的默认值。它们是使用标准 INI 格式的配置文件编写的。

pip 有 3 个 "级别" 的配置文件:

  • global:系统范围的配置文件,跨用户共享
  • user:每个用户的配置文件
  • site:每个环境的配置文件,即:每个虚拟环境

pip 的配置文件位于相当标准的位置,并且这个位置在不同的操作系统上是不同的,利用 pip config 命令 -debug 选项可以进行查询:

1
python -m pip config -debug
1
2
3
4
5
6
7
8
9
env_var:
env:
global:
/Library/Application Support/pip/pip.conf, exists: False
site:
/usr/local/opt/python@3.11/Frameworks/Python.framework/Versions/3.11/pip.conf, exists: False
user:
/Users/borne/.pip/pip.conf, exists: False
/Users/borne/.config/pip/pip.conf, exists: False

此外,环境变量 PIP_CONFIG_FILE 可用于指定首先加载的配置文件,其值将被上述文件中设置的值覆盖。将此值设置为 os.devnull 将禁用所有配置文件的加载。

当存在多个配置文件时,pip 会按照以下顺序组合它们:

  • PIP_CONFIG_FILE(如果设置了的话)

  • global

  • user

  • site

注意:每个文件读取都会覆盖从先前文件读取的任何值,即:site 配置文件的优先级是最高的

下面将展示几个配置文件的设置实例:

设置镜像源(index-url)以及请求超时时间(timeout

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

或者让 pip 走代理(proxy

1
2
[global]
proxy = http://ip:port

简单总结一下,关于 pip 配置文件设置的几个关键点:

  • pip 配置文件格式:ini
  • 设置的名称源自长命令行选项,比如:--index-url
  • 每个子命令都可以在其自己的部分中进行选择性配置,并且将覆盖具有相同名称的全局设置

后记

对于掌握一个工具来说,除了了解这个工具的一些常用命令外,最重要的就是熟悉关于这个工具的配置文件:

  • 知道配置文件在哪
  • 如何对配置文件进行一些常规设置
  • 设置日志文件的位置

知道配置文件在哪以及进行常规配置保证了工具能够按照自己想要的方式运行,设置日志文件的位置能够在工具运行出错时,知道去哪排查错误。

参考


  1. pip documentation v23.1.2 : https://pip.pypa.io/en/stable/↩︎

  2. 还有一种比较常见的解释器 IPython,用 In [序号]: 作为提示符。比如:Anaconda 中的 Spyder↩︎

  3. 通过 help(sys) 可以查询 sys 模块的信息,该模块提供对某些对象的访问,比如:解释器使用或者维护的一些模块(sys.path, sys.argvsys.modules等等)以及和解释器进行强交互的一些函数(stdin, stdoutstderr等等)↩︎

  4. Requirement Specifiers - pip documentation v23.1.2:https://pip.pypa.io/en/stable/reference/requirement-specifiers/#requirement-specifiers↩︎

  5. Requirements File Format - pip documentation v23.1.2:https://pip.pypa.io/en/stable/reference/requirements-file-format/#requirements-file-format↩︎

  6. 事实上,Python 的包安装程序 pip 总是更喜欢 wheel,因为相比于 sdist ,wheel 安装总是更快:https://packaging.python.org/en/latest/overview/↩︎

  7. Configuration - pip documentation v23.1.2:https://pip.pypa.io/en/stable/topics/configuration/#config-file↩︎