setuptools 入门指南:高效打包与发布你的 Python 项目

昨天 1328阅读

在 Python 开发中,将代码封装成可复用、可分发的包是迈向专业开发的重要一步。无论是内部工具共享,还是开源贡献,良好的打包机制都能极大提升项目的可用性与维护性。而 setuptools 正是 Python 官方推荐的核心打包工具之一,它不仅简化了构建流程,还支持依赖管理、版本控制、命令行入口点等关键功能。本文将带你从零开始,掌握使用 setuptools 打包并发布 Python 项目的基本方法。

为什么选择 setuptools?

setuptools 是对早期 distutils 的增强版,提供了更丰富的功能,例如:

  • 自动处理依赖项(通过 install_requires
  • 支持动态发现包结构(find_packages()
  • 可定义命令行脚本入口(entry_points
  • 生成标准化的元数据(如作者、许可证、项目描述等)

这些特性使得 setuptools 成为现代 Python 项目打包的事实标准。

setuptools 入门指南:高效打包与发布你的 Python 项目

项目结构准备

一个典型的可打包 Python 项目通常具有如下结构:

my_project/
├── src/
│   └── my_package/
│       ├── __init__.py
│       └── core.py
├── setup.py
├── pyproject.toml        # (可选,但推荐)
└── README.md

建议将源代码放在 src/ 目录下,这有助于避免开发时意外导入本地模块而非已安装版本。

编写 setup.py

setup.pysetuptools 的核心配置文件。以下是一个基础示例:

# setup.py
from setuptools import setup, find_packages

setup(
    name="my-package",                     # 包名(PyPI 上唯一)
    version="0.1.0",                       # 版本号(遵循语义化版本规范)
    author="Your Name",
    author_email="your.email@example.com",
    description="A short description of your package",
    long_description=open("README.md", encoding="utf-8").read(),
    long_description_content_type="text/markdown",
    url="https://github.com/yourname/my-project",  # 项目主页(非链接推广)
    packages=find_packages(where="src"),   # 自动发现 src/ 下的包
    package_dir={"": "src"},               # 指定包根目录为 src
    python_requires=">=3.7",               # 最低 Python 版本要求
    install_requires=[                     # 依赖列表
        "requests>=2.25.0",
        "click>=8.0",
    ],
    entry_points={                         # 定义命令行工具
        "console_scripts": [
            "mycli=my_package.core:main",
        ],
    },
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
)

上述代码中,find_packages(where="src") 会自动扫描 src/ 目录下的所有 Python 包,避免手动列举。entry_points 则允许用户安装后直接在终端运行 mycli 命令,调用 my_package.core 模块中的 main 函数。

使用 pyproject.toml(现代推荐方式)

自 PEP 517 起,Python 推荐使用 pyproject.toml 作为构建系统的统一配置文件。你可以完全用它替代 setup.py,或两者结合使用。以下是纯 pyproject.toml 的写法:

# pyproject.toml
[build-system]
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "my-package"
version = "0.1.0"
description = "A short description of your package"
readme = "README.md"
authors = [{name = "Your Name", email = "your.email@example.com"}]
license = {text = "MIT"}
classifiers = [
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
]
requires-python = ">=3.7"
dependencies = [
    "requests>=2.25.0",
    "click>=8.0",
]

[project.urls]
Homepage = "https://github.com/yourname/my-project"

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

这种方式更简洁、声明式,且避免了执行任意 Python 代码的风险,是未来的发展方向。

构建与本地测试

在正式发布前,应先在本地构建并测试安装。执行以下命令生成分发文件:

python -m build

该命令会生成 dist/ 目录,包含 .tar.gz(源码分发)和 .whl(二进制轮子)文件。接着可使用 pip 在虚拟环境中测试安装:

pip install dist/my_package-0.1.0-py3-none-any.whl

安装后,验证命令行工具是否可用:

mycli --help

若一切正常,说明打包成功。

发布到 PyPI

当你准备好公开项目时,可将其上传至 Python Package Index(PyPI)。首先安装 twine

pip install twine

然后上传:

twine upload dist/*

系统会提示输入 PyPI 账号凭据(建议使用 API Token 提升安全性)。上传成功后,全球用户即可通过 pip install my-package 安装你的项目。

注意事项与最佳实践

  1. 版本管理:严格遵循 语义化版本(MAJOR.MINOR.PATCH),避免破坏性变更。
  2. 依赖锁定setup.pypyproject.toml 中应指定合理的版本范围,而非固定版本(除非必要)。
  3. README 与 LICENSE:确保包含清晰的使用说明和开源许可证。
  4. 测试覆盖:在发布前运行单元测试,确保功能完整。
  5. 避免硬编码路径:使用相对路径或 importlib.resources 处理资源文件。

总结与建议

setuptools 为 Python 项目提供了强大而灵活的打包能力,无论是小型工具还是大型框架,都能从中受益。对于新项目,强烈建议采用 pyproject.toml 配置方式,以符合现代 Python 打包标准。同时,务必重视元数据完整性与依赖声明准确性,这不仅影响用户体验,也关系到生态系统的健康。

如果你尚未尝试打包自己的项目,不妨从一个简单的工具开始,按照本文步骤操作一次。你会发现,将代码变成可安装、可复用的包,远比想象中简单——而这正是迈向专业 Python 开发者的关键一步。

文章版权声明:除非注明,否则均为Dark零点博客原创文章,转载或复制请以超链接形式并注明出处。