Python 包管理

导航
返回开发工具分类

pip是Python官方的包管理工具,它可以用来安装、升级、卸载Python包。

有关pip的文档和包源,我们可以参考pip官方文档和PyPI包索引,基本使用参考pip安装包

章节目录

  1. pip 常用命令与镜像
  2. 发布 Python 库到 PyPI
  3. 使用 Sphinx 编写项目文档
  4. Sphinx 主题与 Read the Docs

pip常用命令

安装包

1
pip3 install <package-name>

安装特定版本的包

1
pip3 install <package-name>==<version>

查看所有已安装包

1
pip3 list

卸载包

1
pip3 uninstall <package-name>

更新包

1
pip3 install --upgrade <package-name>

搜索包请使用PyPI网站。PyPI已关闭pip search所依赖的XML-RPC搜索接口,不能再将该命令作为默认搜索办法;参见pip说明。

pip换清华源加快速度

临时使用

1
pip3 install -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple some-package

设为默认

1
pip3 config set global.index-url https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple

恢复该配置项为官方源(若仍被覆盖,使用pip3 config debug检查其他配置及环境变量)

1
pip3 config set global.index-url https://pypi.org/simple

创建一个库并发布到PyPI

这里我使用uv 项目管理来管理项目。

创建项目

按照GitHub 代码托管中的仓库管理体系创建仓库,并将项目clone到本地。

初始化项目

由于我要创建一个库,所以初始化时要加入--lib参数。

1
uv init --lib

安装依赖

1
uv add <package-name>

编写代码

在项目中编写代码,确保代码符合Python的规范。

编写pyproject.toml文件

参考pip官方文档打包一个项目

修改项目根目录下的pyproject.toml文件,用于描述项目的元数据和依赖信息。

其中,project-name为分发项目名,project-description为项目描述。分发名与Python导入模块名不必相同,但构建后端必须正确定位实际模块。requires-python应填写代码实际测试支持的版本,不能只改数字就宣称兼容旧版Python。

pyproject.toml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[project]
name = "<project-name>"
version = "1.0.0"
description = "<project-description>"
readme = "README.md"
authors = [
{ name = "<username>", email = "<email>" }
]
requires-python = ">=3.8"
classifiers = [
"Programming Language :: Python :: 3",
"Operating System :: OS Independent",
]
license = "Apache-2.0"
license-files = ["LICENSE"]
dependencies = []

[project.urls]
Homepage = "https://github.com/<username>/<repository-name>"
Issues = "https://github.com/<username>/<repository-name>/issues"

[build-system]
requires = ["uv_build>=0.8.4,<0.9.0"]
build-backend = "uv_build"

使用module-name参数可以实现项目名和包名不同的效果,具体参考uv官方文档build-backend部分。

1
2
[tool.uv.build-backend]
module-name = "<package-name>"

创建workflow

参考uv官方文档GitHub Actions

创建workflow文件的目的是实现自动发布功能,为以后包的更新提供方便。

在.github/workflows目录下添加文件publish-to-pypi.yml文件,用于描述发布项目的工作流程。

文件内容如下:

publish-to-pypi.yml
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
name: Publish to PyPI

on:
push:
tags:
- 'v*'
workflow_dispatch:

jobs:
build-and-publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v6

- name: Install dependencies
run: uv sync

- name: Build package
run: uv build

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}

当匹配v*的tag被推送到GitHub时,workflow才会触发;只在本地创建tag不会触发。上面的示例使用API Token认证,不是Trusted Publishing。

添加Trusted Publisher Management

Trusted Publishing与API Token是两种不同的认证方式,不需要同时配置。选择Trusted Publishing时,在PyPI登记仓库和workflow文件名,并给发布job添加permissions: { contents: read, id-token: write },同时删除发布步骤中的user和password。具体见PyPI官方说明。下面的Token两节只适用于保留上方Token工作流的情况。

注册一个PyPI账号,选择Publishing,添加Trusted Publisher。

1.png

添加GitHub Trusted Publisher。

2.png

这里最常见的问题就是撞名,没办法,一个一个试吧。

danger
PyPI项目名必须满足唯一性要求;已经上传过的分发文件名不能再次使用,即使文件后来被删除。删除不代表文件仍可下载,也不能靠删包重新上传同名文件。发布有误时通常应提高版本号重新构建,详见Filename or contents already exists。

生成PyPI Token

在Account settings中生成token。

3.png

找到API tokens

4.png

按要求填写表单,生成token。项目已存在时优先限定到该项目,妥善保存,不要把令牌贴进代码、日志或截图。

5.png

将Token添加到GitHub Actions

在GitHub仓库中,选择Settings,选择Secrets and variables,选择Actions,点击New repository secret。

6.png

填写从PyPI账号获取的token。

7.png

发布项目

将匹配v*的tag推送到GitHub,才会触发上面的发布workflow;若在Gitee创建tag,需先确认镜像已将该tag同步到GitHub。也可在GitHub Actions中手动触发。

给PyPI项目添加文档

我使用的文档工具是Sphinx,我使用的文档主题是sphinx_rtd_theme,我的文档发布平台是Read the Docs。

Sphinx

安装

1
uv add sphinx

初始化

1
uv run sphinx-quickstart --sep docs

配置

上面的--sep将源文件放入docs/source,与下文路径保持一致。若选择不分离source/build,必须相应调整路径。Python 3.10及更早版本还需安装tomli;MyST和主题插件需按后文先安装再构建。

配置项目信息,其中,通过代码获取版本号填入release变量。

conf.py
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
# Configuration file for the Sphinx documentation builder.
#
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

# -- Project information -----------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information

import sys
from pathlib import Path

FILE = Path(__file__).resolve()
ROOT = FILE.parents[2] # 项目根目录

sys.path.insert(0, str(ROOT / "src"))

if sys.version_info >= (3, 11):
# Python 3.11 或更高
import tomllib as tomli
else:
# Python 3.8 ~ 3.10
import tomli

with open(ROOT / "pyproject.toml", "rb") as f:
config = tomli.load(f)

project = "wliafe-mltools"
copyright = "2025, wliafe"
author = "wliafe"
release = config["project"]["version"]

添加Sphinx插件。

conf.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration

extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.viewcode",
"sphinx.ext.napoleon",
"myst_parser",
"sphinx_rtd_theme",
]

templates_path = ["_templates"]
exclude_patterns = []

language = "zh_CN"

设置html主题。

conf.py
1
2
3
4
5
# -- Options for HTML output -------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output

html_theme = "sphinx_rtd_theme"
html_static_path = ["_static"]

编写index.rst文件

在.. toctree下面列出自己编写的文档。

index.rst
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.. wliafe-mltools documentation master file, created by
sphinx-quickstart on Fri Aug 22 14:27:37 2025.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.

欢迎查看 wliafe-mltools 文档
==========================================

.. toctree::
:maxdepth: 1

入门
api
历史版本

索引和表格
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

自动生成API文档

使用sphinx.ext.autodoc和sphinx.ext.napoleon插件根据代码中的注释自动生成API文档。

在conf.py文件中添加插件。

编写api.rst文件,列出需要生成文档的模块。

api.rst
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
API 文档
========

.. automodule:: mltools
:members:
:undoc-members:
:show-inheritance:

.. autoclass:: mltools.learn.Epoch
:members:
:undoc-members:
:show-inheritance:

.. autoclass:: mltools.utils.Timer
:members:
:undoc-members:
:show-inheritance:

.. autoclass:: mltools.utils.Recorder
:members:
:undoc-members:
:show-inheritance:

.. autoclass:: mltools.draw.Animator
:members:
:undoc-members:
:show-inheritance:

将api.rst添加到index.rst中。

使用Markdown编写文档

使用Markdown编写文档,需要安装myst_parser插件。

1
uv add myst_parser

在conf.py文件中添加插件。

编写Markdown文件,将Markdown文件名添加到index.rst。

本地构建项目

在项目根目录下执行以下命令,构建项目。

1
uv run sphinx-build -M html docs/source docs/build

sphinx_rtd_theme主题

安装

1
uv add sphinx_rtd_theme

配置

将主题作为插件添加到conf.py文件中。

将conf.py文件中的html_theme变量设置为sphinx_rtd_theme。

我使用的是主题的默认配置,如果想配置主题,参考sphinx_rtd_theme。

Read the Docs

使用Github注册Read the Docs账号。

点击Add project,填写信息。

8.png

在项目中添加.readthedocs.yaml文件用于Read the Docs构建项目。

.readthedocs.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
version: 2
build:
os: ubuntu-24.04
tools:
python: '3.12'
sphinx:
configuration: docs/source/conf.py
python:
install:
- requirements: docs/requirements.txt
- requirements: requirements.txt
- method: pip
path: .

info
requirements接收requirements格式文件的路径,并不要求文件必须叫requirements.txt;python.install还支持安装当前项目,供autodoc导入。示例采用Python 3.12,具体版本应与项目和文档依赖相容。参见Read the Docs配置文档。