怎么使用setuptools将Python脚本打包成可安装的wheel包

唐可
唐可
发布时间:2026-11-09 | 9人浏览过
原创

详细介绍如何使用setuptools和build工具将Python脚本或模块打包为标准的wheel(.whl)二进制分发包,包含项目规范结构、pyproject.toml核心配置、构建操作、安装验证与常见问题排查全流程。

Python 工程化分发指南
将写好的 Python 脚本打包为 wheel 包(即 .whl 文件),核心流程是:规范代码结构 → 编写声明元数据与依赖的 pyproject.toml 配置文件 → 安装并调用标准 build 工具执行打包 → 获得预编译归档并在目标环境通过 pip install 一键安装。相比于直接复制单个脚本,wheel 包能自动随包安装第三方依赖,并支持将脚本函数注册为系统全局命令。
怎么使用setuptools将Python脚本打包成可安装的wheel包
图 1:Python 脚本经 setuptools 与 build 构建为标准 Wheel 包的完整运转链路

一、认识 Wheel 包及其解决的问题

在日常开发中,许多人习惯直接将一个 .py 脚本发给同事或部署到服务器上。但这种方式在实际使用中很容易遇到三个问题:一是脚本依赖的第三方库(如 requests、pandas)需要接收方手动逐个安装,稍有遗漏就会报 ModuleNotFoundError;二是单文件无法直接在系统终端中像内置命令一样随处敲命令运行;三是随着功能增加,多文件与配置难以整洁地管理与版本回滚。

Wheel(PEP 427 标准)是 Python 官方推荐的构建分发格式(Built Distribution)。它的本质是一个经过特别组织的 ZIP 归档,扩展名为 .whl。与传统的源码包(sdist,.tar.gz)不同,wheel 包在安装时不需要重新运行 setup.py 脚本,pip 只需要将其解压缩到目标环境的 site-packages 目录,并为其中的控制台入口创建可执行启动脚本。这使得安装过程安全、干净且速度极快。

二、整理项目目录结构

打包前需要为代码建立清晰的工程目录。目前 Python 打包界普遍推荐 src 布局(src-layout),它能有效避免在项目根目录下测试时因 Python 优先导入当前工作区目录而掩盖打包遗漏的问题。

以编写一个名为 my_tool 的实用命令行工具为例,标准项目目录结构组织如下:

my_project/
├── pyproject.toml         # 项目核心构建与打包配置文件
├── README.md              # 项目说明文档(会被打包器读取作为包描述)
├── LICENSE                # 开源协议或授权声明文件
└── src/
    └── my_tool/           # 核心 Python 包目录
        ├── __init__.py    # 包标识文件,可以导出核心函数或版本号
        ├── core.py        # 业务逻辑代码
        └── cli.py         # 命令行终端入口函数

其中各个脚本的代码职责明确分工:

  • src/my_tool/__init__.py:声明包的导出内容,保持简洁:
    # src/my_tool/__init__.py
    __version__ = "0.1.0"
  • src/my_tool/core.py:负责具体的业务逻辑计算:
    # src/my_tool/core.py
    def process_data(text: str) -> str:
        return text.strip().upper()
  • src/my_tool/cli.py:负责命令行交互与入口调用:
    # src/my_tool/cli.py
    import sys
    from my_tool.core import process_data
    
    def main():
        if len(sys.argv) > 1:
            input_text = " ".join(sys.argv[1:])
        else:
            input_text = "hello wheel"
        print(f"[my-tool] 处理结果: {process_data(input_text)}")
    
    if __name__ == "__main__":
        main()
怎么使用setuptools将Python脚本打包成可安装的wheel包
图 2:源代码目录与 Wheel 解包后内部 .dist-info 元数据的映射机制

三、编写打包配置文件 pyproject.toml

在现代 Python 打包标准(PEP 517 和 PEP 518)中,官方推荐使用声明式的 pyproject.toml 替代过去的纯代码形式 setup.py。pyproject.toml 结构清晰,能够在不需要执行任意 Python 脚本的情况下直接解析出项目元数据。

在项目根目录创建 pyproject.toml,写入以下完整内容:

[build-system]
# 声明构建当前 wheel 包所需的底层工具链及后端引擎
requires = ["setuptools>=61.0", "wheel"]
build-backend = "setuptools.build_meta"

[project]
name = "my-tool"
version = "0.1.0"
description = "一个使用 setuptools 打包的示范工具"
readme = "README.md"
requires-python = ">=3.8"
license = { text = "MIT" }
authors = [
    { name = "Developer", email = "developer@example.com" }
]

# 声明当前脚本运行时所依赖的第三方库(按需填写)
dependencies = [
    "requests>=2.28.0"
]

# 关键配置:将 Python 函数注册为终端可直接敲击的全局控制台命令
[project.scripts]
my-cli = "my_tool.cli:main"

[tool.setuptools.packages.find]
# 告知 setuptools 从 src 目录下自动扫描包
where = ["src"]
配置要点解析:
  • [build-system]:指明打包构建由 setuptools.build_meta 接管,这是标准 PEP 517 后端。
  • dependencies:安装该 wheel 包时,pip 会自动检查并安装此处列出的第三方库,彻底解决手动安装依赖的繁琐。
  • [project.scripts]:左侧 my-cli 是你希望用户在终端敲击的命令名,右侧 "my_tool.cli:main" 指向 src/my_tool/cli.py 文件中的 main() 函数。

四、准备构建工具并执行打包

以往很多教程会让用户直接执行 python setup.py bdist_wheel,但在现代标准中,该方式已被官方标记为弃用(Deprecated)。最规范的做法是使用独立的构建驱动器 build(即 PyPA 维护的 pypa/build)。

怎么使用setuptools将Python脚本打包成可安装的wheel包
图 3:setuptools 构建 Wheel 包的操作步骤与阶段性产出检查

1. 安装构建依赖

在当前 Python 环境中升级 setuptools、wheel 并安装 build:

# 示例命令:安装与更新打包工具链
pip install --upgrade setuptools wheel build

2. 执行构建命令

在包含 pyproject.toml 的项目根目录下,运行以下构建命令:

# 示例命令:仅构建 wheel 二进制分发包
python -m build --wheel
运行结果示例:

* Creating isolated environment...
* Installing packages in isolated environment... (setuptools >= 61.0, wheel)
* Getting build dependencies for wheel...
* Building wheel...
Successfully built my_tool-0.1.0-py3-none-any.whl

3. 检查生成产物

构建成功后,项目根目录会新增一个 dist/ 文件夹,里面存放着生成的 .whl 文件:

# 示例输出查看
$ ls dist/
my_tool-0.1.0-py3-none-any.whl

这个单文件就是你可以直接分发给他人、上传至私有包仓库或在生产环境中部署的安装包。

五、本地安装与结果验证

构建完成后,切忌在当前源码开发目录下直接测试,因为当前目录下的 src/ 可能会对 Python 导入产生干扰。推荐新建一个干净的虚拟环境进行验收。

1. 创建并激活全新虚拟环境

# 示例命令:创建临时测试虚拟环境
python -m venv test_env

# 激活虚拟环境(macOS/Linux)
source test_env/bin/activate

# 激活虚拟环境(Windows)
# test_env\Scriptsctivate

2. 安装生成的 Wheel 包

直接使用 pip install 指向刚才生成的 .whl 文件路径:

# 示例命令:安装本地 wheel 包
pip install dist/my_tool-0.1.0-py3-none-any.whl

pip 会自动解包 my_tool 模块到虚拟环境的 site-packages,安装 pyproject.toml 中声明的 requests 依赖,并在虚拟环境的 bin/ 目录下生成名为 my-cli 的可执行脚本。

3. 验证功能与元数据

在终端中直接运行配置好的控制台命令:

# 示例执行
$ my-cli "hello antigravity"
[my-tool] 处理结果: HELLO ANTIGRAVITY

或者通过 Python 解释器导入验证:

$ python -c "import my_tool; print(my_tool.__version__)"
0.1.0

查看包元数据与依赖关系确认安装无误:

$ pip show my-tool
Name: my-tool
Version: 0.1.0
Summary: 一个使用 setuptools 打包的示范工具
Requires: requests

六、常见问题排查与注意事项

初次打包时,开发者往往会遇到一些细节问题。通过以下排查矩阵可以快速定位并修复:

怎么使用setuptools将Python脚本打包成可安装的wheel包
图 4:打包及安装运行过程中的常见报错排查决策路径
故障现象 常见原因 解决方法
终端报错 command not found [project.scripts] 格式错误或未将安装目录加入环境变量 确保写法为 命令名 = "包名.模块名:函数名"(无括号)。若未使用虚拟环境,确认 ~/.local/bin 在系统 PATH 中。
用户运行报 ModuleNotFoundError 未在 dependencies 中声明依赖,误以为本地已有即全局已有 在 pyproject.toml 的 dependencies = [...] 中补齐所有外部依赖库及最低版本要求。
打包后缺少子模块或文件夹 子文件夹内缺少 __init__.py,导致 setuptools 未将其识别为有效 Python 包 在每个包含 Python 文件的子目录中放置一个 __init__.py(即使为空文件)。
静态配置文件(.json/.yaml)未打入 wheel 默认情况下打包器只收集 .py 文件 在 pyproject.toml 中增加配置:
[tool.setuptools.package-data]
my_tool = ["*.json", "assets/*"]

七、打包规范与最佳实践总结

使用 setuptools 打包 Python 脚本并非单纯为了生成一个文件,而是建立标准工程化协作的基础。最后,我们梳理出纯 Python 项目打包的四条关键准则:

怎么使用setuptools将Python脚本打包成可安装的wheel包
图 5:Wheel 命名结构剖析与现代化 setuptools 打包四大准则
  1. 拥抱声明式标准配置:优先采用 pyproject.toml 管理项目元数据与构建依赖,摆脱对复杂脚本式 setup.py 的过度依赖。
  2. 坚持使用 src 目录隔离:让开发源码与构建输出环境严格隔离,彻底杜绝本地路径污染导入路径的问题。
  3. 使用 python -m build 统一构建:利用隔离沙箱机制自动下载构建依赖,避免本地机器环境污染生成的 wheel 包。
  4. 发布前在干净虚拟环境中完成验证:通过 pip install dist/*.whl 全流程跑通安装、依赖拉取和 CLI 命令运行,确保下游用户拿到即用。
相关专题:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表