文章目录

Python 打包分发:setup.py 与 PyPI 发布

发布于 2026-04-06 09:27:41 · 浏览 15 次 · 评论 0 条

Python 打包分发:setup.py 与 PyPI 发布

将你开发的 Python 包发布到 PyPI(Python Package Index),让全球开发者都能通过 pip install 安装使用,这是开源贡献的重要方式。本文将手把手带你完成整个打包与发布流程。


一、为什么需要打包发布

当你开发了一个功能模块,希望他人能够便捷地安装使用时,直接让对方克隆仓库、添加到 PYTHONPATH 的方式过于繁琐。通过标准化的打包发布流程,用户只需一行命令即可完成安装,同时你也能获得版本管理、依赖解决等完整支持。

PyPI 是 Python 官方的软件仓库,类似于 npm 之于 JavaScript、maven 之于 Java。发布到 PyPI 后,你的包可以被全世界的 Python 开发者发现和使用。


二、前期准备工作

2.1 注册 PyPI 账号

访问 https://pypi.org 注册一个账号。记住你的用户名和密码,后续上传时需要用到。

需要注意的是,PyPI 有两个站点:

建议先在测试仓库练习,确认流程无误后再发布到正式仓库。

2.2 安装必要工具

pip install setuptools wheel twine
  • setuptools:Python 包构建的核心工具
  • wheel:二进制分发格式,比源码包安装更快
  • twine:安全上传包到 PyPI 的工具

三、项目目录结构

一个规范的 Python 包应该具有以下结构:

my_package/
├── my_package/          # 包目录(与包名同名)
│   ├── __init__.py      # 包初始化文件
│   ├── module.py        # 模块文件
│   └── ...
├── tests/               # 测试目录(可选)
│   └── test_*.py
├── setup.py             # 构建配置文件
├── setup.cfg            # 附加配置(可选)
├── pyproject.toml       # 现代配置方式(可选)
├── README.md            # 项目说明
├── LICENSE              # 许可证文件
└── requirements.txt     # 依赖列表(可选)

关键点__init__.py 文件的存在告诉 Python 这是一个包,可以为空文件,也可以包含包的版本信息和导入语句。


四、编写 setup.py

setup.py 是 Python 包构建的核心配置文件,定义了包的元数据和构建方式。

4.1 基础配置

from setuptools import setup, find_packages

setup(
    name="my_package",
    version="0.1.0",
    author="Your Name",
    author_email="your.email@example.com",
    description="A short description of the package",
    long_description=open("README.md").read(),
    long_description_content_type="text/markdown",
    url="https://github.com/yourusername/my_package",
    packages=find_packages(),
    classifiers=[
        "Development Status :: 3 - Alpha",
        "Intended Audience :: Developers",
        "Programming Language :: Python :: 3",
        "Programming Language :: Python :: 3.8",
        "Programming Language :: Python :: 3.9",
        "Programming Language :: Python :: 3.10",
        "Programming Language :: Python :: 3.11",
    ],
    python_requires=">=3.8",
    install_requires=[
        "requests>=2.25.0",
        "numpy>=1.20.0",
    ],
)

4.2 关键参数说明

参数 作用 必填
name 包的唯一标识名
version 版本号,遵循语义化版本规范
packages 需要包含的包列表
install_requires 运行依赖列表
python_requires 兼容的 Python 版本
classifiers 包的分类信息,帮助用户筛选

find_packages() 函数会自动发现当前目录下的所有包,无需手动列出。如果你的项目结构简单,也可以直接使用 packages=["my_package"]

4.3 添加可执行脚本

如果你的包包含命令行工具,可以通过 entry_points 参数添加:

setup(
    # ... 其他参数
    entry_points={
        "console_scripts": [
            "mycli=my_package.cli:main",
        ],
    },
)

这样安装后,用户可以直接在终端使用 mycli 命令,它会调用 my_package.cli 模块中的 main 函数。


五、构建分发包

5.1 生成分发文件

在项目根目录下执行:

python setup.py sdist bdist_wheel

这条命令会生成两种分发格式:

  • 源码分发包(sdist).tar.gz 文件,包含原始源代码
  • 二进制分发包(bdist_wheel).whl 文件,预编译的二进制格式,安装更快

执行完成后,项目目录会新增两个文件夹:

  • dist/:包含生成的分发文件
  • build/:构建过程中的临时文件
  • *.egg-info/:元数据信息

5.2 验证分发文件

使用 twine 工具检查包的结构是否正确:

twine check dist/*

如果检测通过,会显示 "Passed"; 如果发现问题,会给出具体的修复建议。


六、上传到 PyPI

6.1 先上传到测试仓库(推荐)

twine upload --repository testpypi dist/*

系统会提示输入用户名和密码。输入你在 https://test.pypi.org 注册的账号信息。

上传成功后,可以安装测试验证:

pip install --index-url https://test.pypi.org/simple/ my_package

6.2 上传到正式仓库

测试确认无误后,执行:

twine upload dist/*

输入正式 PyPI 的用户名和密码。发布成功后,就可以在 https://pypi.org 上搜索到你的包了。


七、版本更新与维护

当需要发布新版本时,按照以下步骤操作:

  1. 修改版本号:编辑 setup.py 中的 version 参数
  2. 更新日志:在 CHANGELOG.mdREADME.md 中记录变更内容
  3. 重新构建:删除旧的 dist/ 目录,重新执行 python setup.py sdist bdist_wheel
  4. 上传新版本twine upload dist/*

PyPI 不允许同一版本号重复上传。如果上传失败,检查是否忘记更新版本号。


八、常见问题与解决方案

8.1 "HTTPError: 400 Bad Request" 上传失败

最常见的原因是版本号重复。修改 setup.py 中的版本号后重新构建上传。

8.2 包导入失败

检查 packages 参数是否正确包含了所有子包。如果使用 find_packages() 后仍然有问题,可以显式列出:packages=["my_package", "my_package.submodule"]

8.3 依赖未正确安装

确保 install_requires 列表中的依赖名称正确。可以临时创建一个虚拟环境测试:python -m venv test_env && source test_env/bin/activate && pip install your_package


九、PyPI 项目页面配置

发布成功后,在 PyPI 项目页面完善以下信息:

设置项 作用
Project description 显示在搜索结果中的摘要
Project URL 指向 GitHub、文档等链接
Author 作者信息
License 开源许可证类型
Classifiers 选择适当的分类标签

这些信息帮助用户更好地发现和理解你的包。


十、使用 pyproject.toml(现代方式)

Python 3.12+ 和最新版本的 setuptools 支持使用 pyproject.toml 作为配置文件:

[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"

[project]
name = "my_package"
version = "0.1.0"
description = "A short description"
readme = "README.md"
requires-python = ">=3.8"
authors = [
    { name = "Your Name", email = "your.email@example.com" }
]
dependencies = [
    "requests>=2.25.0",
]

[project.scripts]
mycli = "my_package.cli:main"

这种方式的优点是配置更简洁,标准化程度更高。

评论 (0)

暂无评论,快来抢沙发吧!

扫一扫,手机查看

扫描上方二维码,在手机上查看本文