内容提要
文章批评Python打包生态工具过多且互不兼容,令用户困惑。作者对比Node.js和.NET的单一工具流程,认为PDM配合PEP 582的__pypackages__方案最接近理想,可免去虚拟环境管理,但Python指导委员会2023年否决了PEP 582。调查显示多数用户希望统一工具、简化流程,而PyPA未能提供完整方案,作者主张其应集中资源支持PDM。
延伸解读
工具泛滥的根源:PyPA 的角色矛盾
文章统计了 14 个打包相关工具,其中绝大多数由 PyPA 维护,但功能最全的 Poetry 和 PDM 却来自独立开发者。PyPA 既制定标准(如 PEP 517)又维护多个重叠工具,却未能推出一个完整方案。这导致初学者面对 pip+venv、Pipenv、Hatch 等多套教程时无所适从,而官方教程甚至不解释各工具差异,进一步加剧混乱。
虚拟环境之痛:为何 PEP 582 是理想替代
文章指出 venv 存在激活状态易忘、依赖系统 Python 路径、项目目录移动即失效等问题。PEP 582 提议的 __pypackages__ 目录类似 node_modules,包随项目存放,无需符号链接,可跨用户运行且移动项目不破坏环境。PDM 已实现该模式,只需 eval "$(pdm --pep582)" 即可启用,但 Python 指导委员会 2023 年否决了该 PEP,使其无法成为官方标准。
对比 Node.js 与 .NET:单一工具链的启示
Node.js 的 npm 和 .NET 的 dotnet CLI 都提供从初始化、装依赖、锁定版本到发布的一体化流程,且无需虚拟环境。npm 的 node_modules 和 package-lock.json 让项目可任意移动、以不同用户运行;dotnet publish 甚至能生成单文件可执行程序。文章认为 Python 生态缺乏这种“一个工具解决所有事”的体验,而 PyPA 的碎片化策略与此背道而驰。
用户调查与作者主张:集中资源支持 PDM
文章引用一项约八千人的调查,显示多数用户希望统一工具、简化流程。作者据此主张 PyPA 应停止维护多个半成品工具,转而集中资源支持 PDM,因为 PDM 已支持 PEP 582、锁定依赖、符合 PEP 621 的 pyproject.toml,并覆盖应用与库的打包需求。尽管 PDM 尚不支持 C 扩展模块,但作者认为其整体方向最接近理想,值得作为官方推荐方案。
Q&A
Python 打包工具为什么被批评为“十四个工具至少多了十二个”?
文章指出 Python 打包生态存在至少 14 个不同工具(如 setuptools、pip、venv、wheel、twine、pip-tools、virtualenvwrapper、pipx、conda、Pipenv、Poetry、Flit、Hatch、PDM),它们功能重叠、互不兼容,且大多数由 PyPA 维护,却没有一个工具能完整覆盖所有需求。这导致用户困惑,违背了 Python 之禅“应该只有一个明显的方式”。
PEP 582 提出的 __pypackages__ 方案有什么优点?为什么被 Python 指导委员会否决?
PEP 582 提议用项目内的 __pypackages__ 目录替代虚拟环境,类似 Node.js 的 node_modules。优点包括:无需符号链接到系统 Python,解决虚拟环境移动后失效的问题;项目目录可被多个系统用户共享;纯 Python 依赖树在 Python 小版本升级时可能只需重命名目录。但该 PEP 于 2018 年提出后进展缓慢,最终在 2023 年被 Python 指导委员会否决,文章未明确说明否决的具体理由。
与 Node.js 和 .NET 相比,Python 的虚拟环境管理有哪些痛点?
文章指出 Python 虚拟环境存在多个问题:激活方式(activate 脚本)可能因 shell 缓存而失败,且初学者容易在脚本或 cronjob 中错误使用激活;虚拟环境紧密依赖创建它的系统 Python,系统 Python 升级或移除会导致环境失效;虚拟环境的位置没有统一标准,不同工具(virtualenvwrapper、Pipenv、Poetry、Hatch)采用不同策略,导致社区分裂。相比之下,Node.js 的依赖直接放在项目内的 node_modules 中,无需激活,可从任意位置、以任意用户运行;.NET 的 dotnet 工具也无需管理环境,发布后可独立运行。
作者认为 PyPA 在 Python 打包生态中扮演了什么角色?它是否成功?
文章指出 PyPA(Python Packaging Authority)维护了绝大多数打包工具(如 setuptools、pip、venv、wheel、twine、pipx、Pipenv、Flit、Hatch),但功能最全的两个工具 Poetry 和 PDM 却不由 PyPA 维护。作者质疑:如果 PyPA 无法产出一个功能完整的工具,且多个项目职责重叠,那么该工作组是否成功?作者还批评 PyPA 的教程让初学者在多个工具间选择却不解释差异,并认为 PyPA 应集中资源支持 PDM。
PDM 工具如何实现类似 PEP 582 的无虚拟环境工作流?具体怎么用?
PDM 支持 PEP 582 模式,通过命令 `eval "$(pdm --pep582)"` 启用后,运行 `pdm init` 时选择不创建虚拟环境,PDM 就会在项目内生成 `__pypackages__` 目录来安装依赖。例如 `pdm add requests` 会将包安装到 `__pypackages__/3.11/lib/` 下,Python 解释器会自动从该目录导入包,无需激活虚拟环境。这样项目可从任意位置、以任意用户运行,且移动项目目录不会破坏环境。
文章认为 Python 打包生态混乱的根本原因是什么?有什么改进建议?
文章认为根本原因在于 PyPA 未能提供统一、完整的解决方案,反而鼓励了更多不兼容工具的出现(如通过 PEP 517 等标准)。作者建议 PyPA 应集中资源支持 PDM,因为 PDM 功能最全(支持 8 项核心功能中的 8 项),且已实现 PEP 582 的无虚拟环境工作流,最接近理想方案。此外,社区调查显示多数用户希望统一工具、简化流程,但 PyPA 未回应这一诉求。