Python 打包发布与版本治理实战
写好了 Python 库,怎么打包发给别人用?pyproject.toml 是什么?版本号怎么管理?本文从项目结构、构建配置到发布 PyPI 的完整流程,讲清 Python 打包发布与版本治理的最佳实践。
一、现代 Python 项目结构
2026 年的 Python 项目标准入口是 pyproject.toml,不再用 setup.py 和 requirements.txt。一个规范的项目结构如下:
myproject/
├── pyproject.toml # 项目配置入口
├── README.md
├── src/
│ └── myproject/ # 包源码
│ ├── __init__.py
│ ├── core.py
│ └── utils.py
├── tests/
│ └── test_core.py
└── .github/
└── workflows/
└── release.yml
用 src/ 布局可以避免测试时误导入未安装的源码,是社区推荐的做法。
安装工具链:
pip install build twine hatchling。build 负责打包,twine 负责发布到 PyPI,hatchling 是现代的构建后端。
二、pyproject.toml 配置
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "myproject"
version = "0.1.0"
authors = [
{ name = "数栈阿布", email = "dev@example.com" }
]
description = "一个示例 Python 工具库"
readme = "README.md"
license = { text = "MIT" }
requires-python = ">=3.9"
dependencies = [
"requests>=2.28",
"pydantic>=2.0",
]
[project.optional-dependencies]
dev = [
"pytest>=7.0",
"black",
"mypy",
]
[project.urls]
Homepage = "https://github.com/user/myproject"
Issues = "https://github.com/user/myproject/issues"
三、构建与本地安装
# 构建 wheel 和 sdist
python -m build
# 产物在 dist/ 目录下
# dist/myproject-0.1.0-py3-none-any.whl
# dist/myproject-0.1.0.tar.gz
# 本地安装(开发模式,改代码不用重装)
pip install -e ".[dev]"
# 检查包内容是否正确
twine check dist/*
四、版本号治理
语义化版本(SemVer)是 Python 社区通用的版本规范:主版本号.次版本号.修订号,如 1.2.3。
| 变更类型 | 版本号变化 | 示例 |
|---|---|---|
| 不兼容的 API 修改 | 主版本号 +1 | 1.4.2 → 2.0.0 |
| 向下兼容的新功能 | 次版本号 +1 | 1.4.2 → 1.5.0 |
| 向下兼容的 Bug 修复 | 修订号 +1 | 1.4.2 → 1.4.3 |
版本号只改 pyproject.toml 里一处即可。也可以用 hatch 或 bump2version 自动管理版本号。
五、发布到 PyPI
# 先测试环境(TestPyPI)
twine upload --repository testpypi dist/*
# 确认没问题后发布正式 PyPI
twine upload dist/*
发布后别人就可以用 pip install myproject 安装你的库了。建议先用 TestPyPI 验证,再发正式版。
六、CI 自动发布
# .github/workflows/release.yml
name: Release
on:
push:
tags: ["v*"]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- run: pip install build twine
- run: python -m build
- uses: pypa/gh-action-pypi-publish@release/v1
with:
password: $ secrets.PYPI_API_TOKEN
打 tag 后 GitHub Actions 自动构建并发布到 PyPI,全程不用本地操作。
七、总结
现代 Python 打包的核心是 pyproject.toml 单一配置入口。构建用 build 工具,发布用 twine,版本号遵循 SemVer。用 GitHub Actions 做 CI 自动发布,打个 tag 就完成一次发版。记住:先在 TestPyPI 验证,再发正式版。