实战指南 | 从零到一:构建并发布你的首个 Python 包到 PyPI

1. 为什么需要打包Python项目?

当你写了一个实用的Python工具或库,想让其他人也能方便地使用时,最直接的方式就是把它发布到PyPI(Python Package Index)上。PyPI是Python官方的包托管平台,全球开发者都可以通过pip install 你的包名来安装你的作品。

想象一下这个场景:你写了一个自动整理电脑桌面文件的脚本,同事看到后也想用。如果直接发.py文件给对方,他需要手动下载依赖、处理路径问题。但如果你把代码打包上传到PyPI,对方只需要一行命令就能安装使用——这才是真正的"程序员友好"。

2. 项目结构规划

一个标准的Python包目录结构应该像这样:

your_package/ ├── pyproject.toml # 构建配置文件(核心) ├── src/ # 源码目录 │ └── your_package/ # 你的包名 │ ├── __init__.py │ └── module.py ├── tests/ # 测试代码 ├── LICENSE # 开源许可证 └── README.md # 项目说明

这里有个新手常踩的坑:很多人喜欢把代码直接放在项目根目录,但这会导致后续打包和导入出现问题。正确的做法是使用src布局,所有代码放在src/包名下。我刚开始时就犯过这个错误,调试了半天导入失败的问题。

3. 编写核心配置文件

pyproject.toml是现代Python打包的核心配置文件,它取代了旧的setup.py。下面是一个完整的配置示例:

[build-system] requires = ["setuptools>=61.0"] build-backend = "setuptools.build_meta" [project] name = "example_package_你的用户名" # 必须是唯一的 version = "0.1.0" authors = [ {name = "你的名字", email = "你的邮箱"}, ] description = "一个简短的描述" readme = "README.md" requires-python = ">=3.8" classifiers = [ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", ] [project.urls] Homepage = "https://github.com/yourname/yourpackage"

几个关键点说明:

  • name必须全局唯一,建议加上你的用户名
  • version遵循语义化版本规范(MAJOR.MINOR.PATCH)
  • classifiers是PyPI的分类标签,完整的列表可以在PyPI官网找到

4. 处理依赖和许可证

4.1 依赖管理

如果你的包依赖其他库,在pyproject.toml中添加:

dependencies = [ "requests>=2.25.0", "numpy<2.0.0", # 可以指定版本范围 ]

建议使用宽松的版本范围(如>=2.25.0而不是==2.25.0),避免与其他包的依赖冲突。

4.2 选择开源许可证

常见的许可证有:

  • MIT:最宽松,允许任意使用
  • Apache 2.0:包含专利授权条款
  • GPL:要求衍生作品也必须开源

创建LICENSE文件,复制你选择的许可证文本。MIT许可证示例:

Copyright (c) 2023 你的名字 Permission is hereby granted... [此处省略完整许可证文本]

5. 构建包

5.1 安装构建工具

pip install --upgrade build

5.2 执行构建

在项目根目录运行:

python -m build

这会生成dist目录,包含两个文件:

  • .tar.gz:源码分发版
  • .whl:构建好的wheel文件

第一次构建时我遇到了ERROR: Unknown distribution option: 'long_description_content_type'错误,后来发现是因为pyproject.toml格式不对。建议复制上面的模板避免这类问题。

6. 上传到PyPI

6.1 注册PyPI账号

  1. 访问 pypi.org 注册账号
  2. 在账号设置中创建API Token(作用域选整个账户)

6.2 安装上传工具

pip install --upgrade twine

6.3 创建配置文件

在用户目录下创建.pypirc(Windows在C:\Users\你的用户名\):

[pypi] username = __token__ password = pypi-你的API令牌

6.4 上传包

twine upload dist/*

上传成功后你会看到类似这样的输出:

Uploading example_package-0.1.0-py3-none-any.whl 100%|█████████████████████| 5.25k/5.25k [00:01<00:00, 3.05kB/s]

7. 验证和版本更新

7.1 安装测试

pip install example-package-你的用户名

7.2 版本更新流程

  1. 修改代码后,更新pyproject.toml中的version
  2. 重新构建:python -m build
  3. 上传新版本:twine upload dist/*

记住永远不要重复上传同一个版本号的文件,PyPI不允许覆盖已发布的版本。如果上传出错,必须增加版本号重新发布。

8. 高级技巧和常见问题

8.1 包含非Python文件

如果需要打包数据文件(如CSV、图片等),创建MANIFEST.in文件:

include src/your_package/data/*.csv

8.2 测试PyPI

正式发布前,可以先用测试平台验证:

twine upload --repository testpypi dist/*

测试PyPI地址:https://test.pypi.org

8.3 常见错误解决

  • 403 Forbidden:检查API Token是否正确
  • 400 File already exists:增加版本号重新构建
  • 导入错误:确保__init__.py文件存在

我第一次上传时因为网络问题失败了三次,后来发现用国内镜像源可能会出现问题,建议直接连接PyPI主站。