setuptools 入门指南:高效打包与发布你的 Python 项目
在 Python 开发中,将代码封装成可复用、可分发的包是迈向专业开发的重要一步。无论是内部工具共享,还是开源贡献,良好的打包机制都能极大提升项目的可用性与维护性。而 setuptools 正是 Python 官方推荐的核心打包工具之一,它不仅简化了构建流程,还支持依赖管理、版本控制、命令行入口点等关键功能。本文将带你从零开始,掌握使用 setuptools 打包并发布 Python 项目的基本方法。
为什么选择 setuptools?
setuptools 是对早期 distutils 的增强版,提供了更丰富的功能,例如:
- 自动处理依赖项(通过
install_requires) - 支持动态发现包结构(
find_packages()) - 可定义命令行脚本入口(
entry_points) - 生成标准化的元数据(如作者、许可证、项目描述等)
这些特性使得 setuptools 成为现代 Python 项目打包的事实标准。

项目结构准备
一个典型的可打包 Python 项目通常具有如下结构:
my_project/
├── src/
│ └── my_package/
│ ├── __init__.py
│ └── core.py
├── setup.py
├── pyproject.toml # (可选,但推荐)
└── README.md
建议将源代码放在 src/ 目录下,这有助于避免开发时意外导入本地模块而非已安装版本。
编写 setup.py
setup.py 是 setuptools 的核心配置文件。以下是一个基础示例:
# 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 安装你的项目。
注意事项与最佳实践
- 版本管理:严格遵循 语义化版本(MAJOR.MINOR.PATCH),避免破坏性变更。
- 依赖锁定:
setup.py或pyproject.toml中应指定合理的版本范围,而非固定版本(除非必要)。 - README 与 LICENSE:确保包含清晰的使用说明和开源许可证。
- 测试覆盖:在发布前运行单元测试,确保功能完整。
- 避免硬编码路径:使用相对路径或
importlib.resources处理资源文件。
总结与建议
setuptools 为 Python 项目提供了强大而灵活的打包能力,无论是小型工具还是大型框架,都能从中受益。对于新项目,强烈建议采用 pyproject.toml 配置方式,以符合现代 Python 打包标准。同时,务必重视元数据完整性与依赖声明准确性,这不仅影响用户体验,也关系到生态系统的健康。
如果你尚未尝试打包自己的项目,不妨从一个简单的工具开始,按照本文步骤操作一次。你会发现,将代码变成可安装、可复用的包,远比想象中简单——而这正是迈向专业 Python 开发者的关键一步。

