Python 打包发布与版本治理实战

写好了 Python 库,怎么打包发给别人用?pyproject.toml 是什么?版本号怎么管理?本文从项目结构、构建配置到发布 PyPI 的完整流程,讲清 Python 打包发布与版本治理的最佳实践。

Python 打包发布配图:蓝色渐变背景上礼盒装入集装箱,流水线箭头,扁平科技插画
Python 打包:从源码到可分发 wheel 文件的完整流水线

一、现代 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 修改主版本号 +11.4.2 → 2.0.0
向下兼容的新功能次版本号 +11.4.2 → 1.5.0
向下兼容的 Bug 修复修订号 +11.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 验证,再发正式版。