如何将 Python 包发布到 PyPI:完整指南
·
文章目录
简介
PyPI(Python Package Index)是 Python 官方的第三方软件仓库,是分发 Python 包的标准平台。本文将详细介绍如何准备、打包并发布Python 项目到 PyPI,并能让其他开发者通过 pip install 来使用您的包。
前期准备
1. 注册 PyPI 账户
首先,需要在以下两个平台注册账户:
- PyPI 正式环境: https://pypi.org/account/register/
- PyPI 测试环境: https://test.pypi.org/account/register/
先在测试环境中练习发布流程,确保一切正常后再发布到正式环境。
2. 安装必要工具
pip install --upgrade pip
pip install --upgrade build
pip install --upgrade twine
build: 用于构建分发包twine: 用于上传包到 PyPI
项目结构准备
一个标准的 Python 包应该具有以下结构:
my_package/
├── src/
│ └── my_package/
│ ├── __init__.py
│ └── module.py
├── tests/
│ └── test_module.py
├── README.md
├── LICENSE
├── pyproject.toml
└── setup.py (可选)
关键文件说明
1. pyproject.toml (推荐)
这是现代 Python 包的标准配置文件:
[build-system]
requires = ["setuptools>=45", "wheel"]
build-backend = "setuptools.build_meta"
[project]
name = "my-awesome-package"
version = "0.1.0"
authors = [
{name = "Your Name", email = "your.email@example.com"},
]
description = "A small example package"
readme = "README.md"
license = {text = "MIT"}
requires-python = ">=3.7"
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
]
keywords = ["example", "package", "tutorial"]
dependencies = [
"requests>=2.25.0",
"numpy>=1.20.0",
]
[project.optional-dependencies]
dev = [
"pytest>=6.0",
"black",
"flake8",
]
[project.urls]
Homepage = "https://github.com/yourusername/my-awesome-package"
Repository = "https://github.com/yourusername/my-awesome-package"
Documentation = "https://my-awesome-package.readthedocs.io/"
"Bug Tracker" = "https://github.com/yourusername/my-awesome-package/issues"
[project.scripts]
my-command = "my_package.cli:main"
2. setup.py (传统方式,仍被广泛支持)
from setuptools import setup, find_packages
with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()
setup(
name="my-awesome-package",
version="0.1.0",
author="Your Name",
author_email="your.email@example.com",
description="A small example package",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/yourusername/my-awesome-package",
project_urls={
"Bug Tracker": "https://github.com/yourusername/my-awesome-package/issues",
},
classifiers=[
"Development Status :: 3 - Alpha",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
],
package_dir={"": "src"},
packages=find_packages(where="src"),
python_requires=">=3.7",
install_requires=[
"requests>=2.25.0",
"numpy>=1.20.0",
],
extras_require={
"dev": [
"pytest>=6.0",
"black",
"flake8",
],
},
entry_points={
"console_scripts": [
"my-command=my_package.cli:main",
],
},
)
3. README.md
编写清晰的说明文档,包括:
- 项目简介
- 安装方法
- 使用示例
- API 文档
- 贡献指南
4. LICENSE
选择合适的开源许可证,常见的有:
- MIT License(最宽松)
- Apache License 2.0
- GNU GPL v3(最严格)
版本管理
语义化版本控制
遵循 Semantic Versioning 标准:
- 主版本号:不兼容的 API 修改
- 次版本号:向下兼容的功能新增
- 修订版本号:向下兼容的问题修正
例如:1.2.3
动态版本管理
可以使用工具自动管理版本号:
# src/my_package/__init__.py
__version__ = "0.1.0"
# pyproject.toml
[project]
dynamic = ["version"]
[tool.setuptools.dynamic]
version = {attr = "my_package.__version__"}
构建和发布流程
本地测试
在发布前,确保包能正确安装和使用:
# 构建包
python -m build
# 本地安装测试
pip install dist/my_awesome_package-0.1.0-py3-none-any.whl
# 测试导入
python -c "import my_package; print(my_package.__version__)"
发布到测试环境
-
注册Test PyPI账号和获取API密钥,如下图所示

-
安装发布工具
pip install twine -
检查包的有效性
twine check dist/*
-
上传到测试PyPI,输入api密钥
twine upload --repository testpypi dist/*
发布到正式环境
-
注册PyPI账号和获取API密钥,如下图所示

-
上传包到正式环境
twine upload dist/*
使用配置文件上传到Pypi
-
创建
~/.pypirc文件:[distutils] index-servers = pypi testpypi [pypi] username = __token__ password = pypi-your-api-token-here [testpypi] repository = https://test.pypi.org/legacy/ username = __token__ password = pypi-your-test-api-token-here -
上传到测试环境
twine upload --repository testpypi dist/* -
上传到正式环境
twine upload dist/*
测试上传的包
-
建立一个新项目,测试刚刚发布的包
pip install dlt645
-
调用函数,测试通过

自动化发布
使用 GitHub Actions
创建 .github/workflows/publish.yml:
name: Publish to PyPI
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install build twine
- name: Build package
run: python -m build
- name: Publish to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: twine upload dist/*
常见问题和解决方案
1. 包名冲突
如果包名已被占用,需要选择其他名称。可以:
- 添加前缀或后缀
- 使用更具描述性的名称
2. 上传失败
常见原因:
- 版本号重复
- 认证信息错误
- 网络连接问题
3. 安装后导入失败
检查:
- 包结构是否正确
__init__.py文件是否存在- 模块路径是否正确
维护和更新
发布新版本
- 更新版本号
- 更新 CHANGELOG
- 构建新包
- 上传到 PyPI
废弃旧版本
可以在 PyPI 上标记特定版本为已废弃,但不能删除已发布的版本。
更多推荐

所有评论(0)