Python打包之pyproject.toml全方位使用指南

 更新时间:2025年11月14日 11:22:37   作者:半截的诗_218  
pyproject.toml 是一个配置文件,用于定义 Python 项目的构建、依赖管理和项目元数据,下面这篇文章主要介绍了Python打包之pyproject.toml的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

在我们的系列文章中,我们已经深入探讨了 setup.pyconda-build 这两种强大的打包工具。您可能已经注意到,社区正在逐步从使用 setup.py 这个可执行的 Python 脚本,转向一个名为 pyproject.toml 的静态配置文件。

这不仅仅是一个简单的文件格式变化,它代表了 Python 打包理念的一次重要演进。为什么需要这个新文件?它又该如何使用呢?

本文将为您全面解析 pyproject.toml,这个被 PEP 518 和 PEP 621 等提案确立为官方标准的现代化打包工具。

一、 开发者篇:使用pyproject.toml定义你的项目

作为项目的创建者,拥抱 pyproject.toml 能让你的项目配置更清晰、更标准,并能将以往散落在各种文件(setup.py, setup.cfg, MANIFEST.in 等)中的配置统一起来。

1. 为什么要使用pyproject.toml?

  • 标准化:它是官方指定的、统一的 Python 项目配置文件格式。
  • 声明式,非可执行:与 setup.py 不同,toml 文件是静态的,只声明“是什么”,而不是执行“做什么”。这使得构建过程更安全、更可预测。
  • 统一配置入口:它不仅能定义项目元数据和依赖,还能统一存放 black, pytest, ruff, mypy 等开发工具的配置,让项目根目录更整洁。
  • 构建系统解耦:它允许你自由选择构建后端(如 setuptools, poetry, pdm, hatch),而不仅仅是绑定 setuptools

2. 如何创建pyproject.toml?

pyproject.toml 是一个基于 TOML (Tom’s Obvious, Minimal Language) 语法的文本文件,您需要在项目根目录手动创建它。

项目结构示例:

my_modern_project/
├── my_awesome_tool/
│   ├── __init__.py
│   └── main.py
├── tests/
│   └── test_main.py
└── pyproject.toml   <-- 我们要创建的文件

pyproject.toml 文件详解:

一个遵循 PEP 621 标准的现代化 pyproject.toml 核心内容如下:

# pyproject.toml

# 1. 构建系统声明 (必需)
# 告诉 pip 等工具,这个项目需要用什么来构建 (这里是 setuptools)
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"

# 2. 项目核心元数据 (必需)
# 这部分取代了 setup.py 中的大部分参数
[project]
name = "my-awesome-tool"
version = "0.1.0"
authors = [
  { name="你的名字", email="你的邮箱@example.com" },
]
description = "一个功能强大的现代工具"
readme = "README.md" # 指定 README 文件
requires-python = ">=3.9"
license = { text = "MIT" }
classifiers = [
    "Programming Language :: Python :: 3",
    "License :: OSI Approved :: MIT License",
    "Operating System :: OS Independent",
]

# 3. 依赖项 (核心)
# 这取代了 setup.py 中的 install_requires
dependencies = [
    "requests>=2.20",
    "numpy",
    "click",
]

# 4. 命令行工具 (可选)
# 这取代了 setup.py 中的 entry_points
[project.scripts]
awesome_tool = "my_awesome_tool.main:cli"

# 5. 可选依赖 (可选)
# 允许用户安装额外功能,例如 pip install "my-awesome-tool[extra]"
[project.optional-dependencies]
extra = ["pandas"]

# 6. 项目链接 (可选)
[project.urls]
Homepage = "https://github.com/your_username/my_modern_project"
"Bug Tracker" = "https://github.com/your_username/my_modern_project/issues"

可以看到,它的结构清晰、可读性强,并且几乎涵盖了 setup.py 的所有核心功能。

3. 开发和安装

开发流程与 setup.py 完全相同。您依然需要在一个虚拟环境中进行开发,并使用 pip 以可编辑模式安装:

# 在激活虚拟环境后,于项目根目录运行
pip install -e .

pip (较新版本) 会自动识别 pyproject.toml 文件,并根据其中的配置来正确安装项目及其依赖。

二、 用户篇:如何使用pyproject.toml定义的项目

作为用户,你可能根本感觉不到任何区别,这正是 pyproject.toml 标准化的美妙之处。

1. 安装流程

当你从 GitHub 下载了一个包含 pyproject.toml 的项目后,安装步骤和传统项目一模一样

  1. 创建并激活虚拟环境 (依然是最佳实践)。
  2. 安装项目
    • 作为普通用户使用:pip install .
    • 作为贡献者开发:pip install -e .

pip 会在后台自动处理所有事情。它会读取 pyproject.toml,理解项目的构建需求和依赖,然后下载并安装所有需要的东西。用户无需关心底层是用 setuptools 还是 poetry 构建的。

三、 总结与优势

pyproject.toml 是 Python 打包的未来,它的优势非常明显:

特性setup.py (传统方式)pyproject.toml (现代方式)
文件格式Python 脚本,可执行TOML 配置文件,声明式
标准性事实标准,但配置分散官方标准 (PEP 518/621)
配置配置分散在 setup.py, setup.cfg 等多个文件中集中管理,可包含项目元数据、依赖和各种开发工具的配置
安全性执行任意代码有潜在风险静态文件,更安全,构建过程更可预测
灵活性强绑定 setuptools可自由选择构建后端 (setuptools, poetry, pdm, hatch 等)

四、 那如果项目文件里既有setup.py又有pyproject.toml呢?

pyproject.toml 是现代 Python 打包流程的唯一入口,它的优先级更高。

当一个构建工具(例如 pip)开始工作时,它会首先寻找 pyproject.toml。这个文件决定了接下来该做什么,以及由谁(哪个构建后端)来做。

下面我们来详细分解一下具体的读取和处理逻辑。

读取流程:三步走

  1. 入口 (pyproject.toml 的 [build-system] 部分)

    • pip 首先打开 pyproject.toml,并且只读取 [build-system] 这个表格。
    • 这个表格告诉 pip:“嘿,要构建这个项目,你需要使用 setuptools(或者 poetry, pdm 等)这个工具。”
    • pip 会确保这个构建工具被安装,然后把控制权完全交给它。
  2. 构建后端接管 (例如 setuptools)

    • 现在,setuptools (作为构建后端) 开始工作。它的任务是收集项目的所有元数据(包名、版本、依赖等)。
    • setuptools 会再次查看 pyproject.toml 文件,寻找一个名为 [project] 的表格。
  3. 元数据读取的优先级

    • 这就是决定性的步骤,会根据文件内容分为以下几种情况:

两种主要场景

场景一:现代项目 (最佳实践)

  • 文件状态:
    • pyproject.toml:包含了完整的 [project] 表格,里面定义了 name, version, dependencies 等所有核心信息。
    • setup.py要么不存在,要么是一个非常简单的“垫片”文件,内容可能只有:
      # setup.py (shim)
      from setuptools import setup
      setup()
      
  • 读取方式:
    • setuptools优先读取 pyproject.toml 中的 [project] 表格作为所有元数据的“唯一真实来源”。
    • 它会忽略 setup.py 文件中的任何元数据(如果有的话)。
    • 那个简单的 setup.py 文件仅仅是为了兼容一些非常老旧的、不认识 pyproject.toml 的工具。

结论:在这种模式下,pyproject.toml 完胜。

场景二:过渡期项目 (非常普遍)

  • 文件状态:
    • pyproject.toml:只包含了 [build-system] 表格,可能还有一些工具配置(如 [tool.pytest]),但没有 [project] 表格
    • setup.py:包含一个完整的 setup() 函数,里面定义了 name, version, install_requires 等所有信息。
  • 读取方式:
    • pip 仍然从 pyproject.toml 开始,得知需要使用 setuptools
    • setuptools 接管后,在 pyproject.toml找不到 [project] 表格
    • 于是,setuptools回退 (fallback) 到它的传统模式:去执行 setup.py 文件,并从 setup() 函数的参数中提取所有的项目元数据。

结论:在这种模式下,pyproject.toml 扮演“指路人”的角色,而 setup.py 仍然是“信息提供者”。

总结与建议

场景pyproject.toml 内容setup.py 内容读取优先级 / 谁说了算?
现代包含 [build-system][project]不存在或仅为简单垫片pyproject.toml 说了算。元数据从 [project] 表格读取。
过渡仅包含 [build-system]包含完整的 setup() 函数setup.py 说了算pyproject.toml 仅用于指定构建工具。
冲突 (应避免)[project]setup() 都定义了元数据[project]setup() 都定义了元数据pyproject.toml 说了算setuptools 会优先采用 [project] 表格中的值。

如果 pyproject.toml 文件中包含了完整的 [project] 表格(定义了项目名称、版本、依赖等),同时又存在一个完备的 setup.py 文件,那么现代化的构建工具(如新版 pipsetuptools)会:默认优先使用 pyproject.toml 文件中的信息。

pyproject.toml 是官方指定的“新版蓝图”,而 setup.py 是“旧版蓝图”。当两种蓝图都在时,构建系统会默认遵循更新、更标准的那一份。旧的 setup.py 文件中的配置在很大程度上会被忽略,以避免冲突和混淆。

到此这篇关于Python打包之pyproject.toml全方位使用的文章就介绍到这了,更多相关Python打包pyproject.toml内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅析Python条件语句中的解密逻辑与控制流

    浅析Python条件语句中的解密逻辑与控制流

    这篇文章主要想来和大家一起探索一下Python条件语句的奇妙世界——解密逻辑与控制流,文中的示例代码讲解详细,感兴趣的小伙伴可以学习一下
    2023-07-07
  • NumPy统计函数的实现方法

    NumPy统计函数的实现方法

    这篇文章主要介绍了NumPy统计函数的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • Python OpenCV学习之图形绘制总结

    Python OpenCV学习之图形绘制总结

    在图像的任务中,不管是图像检测还是图像识别,我们都需要通过绘制图形和绘制文字对处理的结果进行说明,本篇就详细介绍下OpenCV中的图形的绘制,感兴趣的可以了解一下
    2022-01-01
  • 利用keras加载训练好的.H5文件,并实现预测图片

    利用keras加载训练好的.H5文件,并实现预测图片

    今天小编就为大家分享一篇利用keras加载训练好的.H5文件,并实现预测图片,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-01-01
  • Python 类,property属性(简化属性的操作),@property,property()用法示例

    Python 类,property属性(简化属性的操作),@property,property()用法示例

    这篇文章主要介绍了Python 类,property属性(简化属性的操作),@property,property()用法,结合实例形式分析了Python类的定义、属性、方法及相关使用技巧,需要的朋友可以参考下
    2019-10-10
  • 使用Python和Go实现服务器发送事件(SSE)

    使用Python和Go实现服务器发送事件(SSE)

    在当今的交互式web应用程序中,实时数据更新在增强用户体验方面起着至关重要的作用,在实时通信的各种技术中,SSE在众多解决方案脱颖而出,本文给大家介绍了使用Python和Go实现服务器发送事件(SSE),需要的朋友可以参考下
    2024-11-11
  • python打包多类型文件的操作方法

    python打包多类型文件的操作方法

    这篇文章主要介绍了python打包多类型文件的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • 利用Python代码制作过年春联

    利用Python代码制作过年春联

    这篇文章主要介绍了如何利用代码编写过年的春联,文中一共介绍了两种方法,一是利用HTML+CSS+JS,二是利用Python,感兴趣的可以试一试
    2022-01-01
  • Python+Requests+PyTest+Excel+Allure 接口自动化测试实战

    Python+Requests+PyTest+Excel+Allure 接口自动化测试实战

    本文主要介绍了Python+Requests+PyTest+Excel+Allure 接口自动化测试实战,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • pandas中df.groupby()方法深入讲解

    pandas中df.groupby()方法深入讲解

    在使用pandas进行数据统计分析时遇到了问题,找了很久才找到解决办法,所以下面这篇文章主要给大家介绍了关于pandas中df.groupby()方法的相关资料,需要的朋友可以参考下
    2022-12-12

最新评论