Python和Pip升级实战指南:跨平台版本管理与路径一致性

📅 2026/7/6 10:51:55
Python和Pip升级实战指南:跨平台版本管理与路径一致性
1. 为什么升级 Python 和 Pip 是每个开发者绕不开的“日常维护”而不是可有可无的“高级操作”你有没有遇到过这样的情况在 Windows 上用pip install pandas安装一个包报错说“SSL certificate verify failed”在 macOS 上运行python3 -m pip install --upgrade pip终端却冷冷地回你一句“command not found”或者在 Ubuntu 服务器上明明apt list --installed | grep python3显示已安装python3.10但python3 --version却还是固执地输出3.8.10这些不是玄学也不是你手气不好而是 Python 和 Pip 的版本管理、路径配置、权限机制在真实世界里交织碰撞后最典型的“落地噪音”。我从 2012 年开始带团队做数据工程亲手部署过超过 200 台开发机和生产服务器覆盖 Windows 10/11、macOS Monterey 至 Sonoma、Ubuntu 18.04 到 24.04、CentOS 7/8、甚至树莓派上的 Raspbian。这十多年里我见过太多人把“升级 Python”当成一次性的“重装软件”——下载个安装包点下一步就完事也见过太多人把“升级 Pip”当成一句命令的事结果在 CI/CD 流水线上卡住一整天。真相是Python 和 Pip 的升级本质上是一场对操作系统底层环境、用户权限模型、包管理哲学的系统性校准。它不难但必须“懂逻辑”不能只靠复制粘贴。核心关键词就三个Python 版本管理、Pip 包管理、跨平台路径一致性。它们共同决定了你的代码能不能跑、第三方库能不能装、安全漏洞会不会被利用。比如Python 3.9.18 修复了 CVE-2023-27043一个影响email模块的严重解析漏洞而 Pip 23.3.1 修复了 CVE-2023-47248一个允许恶意包在安装时执行任意代码的漏洞。这些不是新闻标题是你明天写爬虫、做 API 接口、处理用户上传文件时真实存在的风险边界。这篇文章不是教科书也不是官方文档的翻译。它是我把十年间在客户现场、内部培训、深夜救火中积累下来的“血泪经验”拆解成一套可复现、可验证、可排查的操作手册。无论你是刚装好 VS Code 的大学生还是管理着 50 人研发团队的技术负责人只要你还在用 Python 写代码、装包、部署服务这篇内容就值得你花 20 分钟读完并把它存进你的个人知识库。它不承诺“一键解决所有问题”但它能让你在下次遇到pip: command not found时不再打开搜索引擎狂刷 15 分钟而是直接打开终端用三行命令定位根源。2. 升级前的必做功课看清现状才能精准出手很多人的升级失败根本原因不是操作错了而是连自己当前的“战场地图”都没搞清楚。就像修车前不看油表、不听异响直接拧螺丝结果越修越糟。在敲下任何一条upgrade命令之前你必须完成三项基础侦察任务确认当前 Python 解释器的真实身份、摸清 Pip 的实际安装位置、理解你所用系统的默认行为逻辑。这三步做完后面 90% 的“诡异错误”都能提前规避。2.1 精确识别你的 Python 解释器python、python3、py到底谁说了算Windows、macOS、Linux 对 Python 可执行文件的命名约定是跨平台混乱的起点。很多人以为python --version和python3 --version输出一样就万事大吉其实完全不是。Windows 用户现代 WindowsWin10 1903默认安装了“Python Launcher”py命令。它是一个智能调度器会根据你的脚本头部#! python3.11或命令行参数py -3.11来调用对应版本。但如果你直接打python它调用的很可能是旧版 Python 2.7如果还残留着或者是某个 Anaconda 环境里的 Python甚至是 Visual Studio 自带的 Python。所以Windows 上最可靠的命令是py -3 --version和py -3.11 --version把 3.11 换成你想查的具体版本。where python只能告诉你 PATH 里第一个python.exe在哪但无法告诉你它是不是你真正想用的那个。macOS 用户macOS 系统自带 Python 2.7已废弃但不会自带 Python 3。你通过 Homebrew、pyenv 或官网安装的 Python 3其可执行文件几乎都放在/usr/local/bin/python3或/opt/homebrew/bin/python3Apple Silicon。此时which python3是有效的但which python很可能指向/usr/bin/python即系统 Python 2.7绝对不要用python命令来管理你的现代 Python 项目。这是 macOS 上最常踩的坑。Linux 用户以 Ubuntu/Debian 为例python命令在较新版本中已被移除或指向python3但python3才是唯一权威。which python3通常返回/usr/bin/python3但要注意/usr/bin/python3往往是python3.x的符号链接例如ls -l /usr/bin/python3可能显示python3 - python3.10。这意味着sudo apt install python3升级的其实是python3.10这个具体包而/usr/bin/python3这个链接会自动更新。但如果你用pyenv安装了 Pythonwhich python3就会指向~/.pyenv/shims/python3这是完全不同的管理路径。提示执行python -c import sys; print(sys.executable)和python3 -c import sys; print(sys.executable)。这个命令会打印出 Python 解释器二进制文件的绝对路径这才是它真正的“身份证”。比which或where更可靠因为它告诉你程序实际从哪里加载而不是 PATH 里哪个路径先被找到。2.2 彻底搞懂 Pip 的“寄生关系”它不是独立软件而是 Python 的“内置器官”Pip 不像 Chrome 或 VS Code 那样是一个独立安装的程序。它是作为 Python 标准库的一部分自 Python 3.4 起被捆绑发布的。这意味着Pip 的生命周期完全依附于它所对应的 Python 解释器。你用python3.10安装的 Pip只能被python3.10调用你用python3.11安装的 Pip只能被python3.11调用。它们之间互不兼容也不能共享。所以当你看到pip --version输出pip 21.0.1 from /usr/lib/python3.8/site-packages/pip (python 3.8)你就该立刻明白这个 Pip 是为 Python 3.8 服务的。如果你现在想用 Python 3.11那么pip命令很可能根本不存在或者它指向的是另一个旧版本的 Pip。正确的做法永远是用目标 Python 解释器来调用 Pip 模块即python3.11 -m pip。这个语法强制指定了 Pip 的“宿主”杜绝了所有歧义。注意pip命令本身只是一个便捷的 shell 别名或脚本它的存在与否、指向何方完全取决于你的 PATH 和安装方式。而python -m pip是 Python 解释器内置的、100% 可靠的调用方式。在所有正式文档、CI/CD 脚本、团队规范中我都强制要求使用后者。2.3 环境变量 PATH 是你的“交通指挥中心”必须亲手绘制一张地图PATH 环境变量就是操作系统查找可执行文件的“寻宝地图”。当你输入python3系统就按 PATH 中列出的目录顺序一个一个去找有没有叫python3的文件。一旦找到第一个就立刻执行后面的目录全被忽略。这就是为什么which python3可能返回/usr/local/bin/python3而which pip却返回/home/username/.local/bin/pip——因为这两个目录都在你的 PATH 里且/usr/local/bin排在/home/username/.local/bin前面。要绘制这张地图只需在终端里执行echo $PATHmacOS/Linux或echo %PATH%Windows CMD。你会看到一长串用冒号:或分号;分隔的路径。关键是要理解这些路径的来源/usr/bin、/bin系统级目录存放操作系统自带的核心命令。/usr/local/bin用户手动编译安装或通过 Homebrew 安装的软件通常在这里。~/.local/binLinux/macOS或%USERPROFILE%\AppData\Roaming\Python\Python311\ScriptsWindowspip install --user命令安装的可执行脚本如pip,black,flake8的默认位置。它属于“用户级”无需管理员权限。C:\Users\YourName\AppData\Local\Programs\Python\Python311\ScriptsWindows官方 Python 安装器勾选“Add Python to PATH”后添加的路径里面放着pip.exe、idle.exe等。实操心得我从不依赖安装器自动修改 PATH。在 Windows 上我会手动检查“系统属性 高级 环境变量”确保C:\Users\YourName\AppData\Local\Programs\Python\Python311\Scripts和C:\Users\YourName\AppData\Local\Programs\Python\Python311都在 PATH 里且前者在后者前面因为 Scripts 目录里有pip.exe。在 macOS/Linux 上我会在~/.zshrc或~/.bash_profile里显式追加export PATH$HOME/.local/bin:$PATH这样就能优先使用--user安装的工具避免与系统级工具冲突。3. 三大平台升级实战不是“照着做”而是“理解为什么这么做”现在我们进入核心环节。下面的每一步我都会解释清楚背后的原理、设计意图以及如果不这么做可能会引发什么连锁反应。这不是一份“菜谱”而是一份“作战地图”。3.1 Windows用“官方安装器”升级是唯一推荐方案其他都是权宜之计Windows 的 Python 生态最大的特点是“碎片化”。你可以通过 Microsoft Store 安装、通过 Chocolatey 安装、通过 pyenv-win 安装甚至通过 WSL 安装。但所有这些方式最终都服务于一个目标让py命令能稳定、可靠地工作。因此我的建议非常明确对于绝大多数 Windows 开发者升级 Python 和 Pip 的黄金标准就是使用 python.org 官方提供的 MSI 安装器。3.1.1 为什么必须下载并运行官方 MSI 安装器完整性保障MSI 安装器不仅包含 Python 解释器还包含pip、setuptools、wheel、idle、tkinter支持库以及最重要的Scripts目录里面有pip.exe、pythonw.exe等。它是一个经过微软签名、全链路测试的完整发行版。PATH 管理可控安装器提供了清晰的“Add Python to PATH”复选框。勾选它安装器会自动将C:\Users\YourName\AppData\Local\Programs\Python\Python311和C:\Users\YourName\AppData\Local\Programs\Python\Python311\Scripts添加到你的用户 PATH 中。这个过程是原子的、可逆的卸载时会自动清理。多版本共存友好官方安装器默认安装到AppData\Local\Programs\Python\下每个版本一个独立文件夹如Python311,Python312。py命令可以完美识别并切换它们互不干扰。提示如果你在公司内网经常遇到 SSL 证书错误不要急着去禁用证书验证那是危险操作。请先尝试在浏览器中访问 https://www.python.org/downloads/ 确认你能正常下载安装包。如果不行说明是公司代理或防火墙策略问题应联系 IT 部门获取合规的证书根证书然后导入到 Windows 证书存储中。这是唯一安全的解决方案。3.1.2 升级 Pip 的正确姿势py -3 -m pip install --upgrade pip安装完新版本 Python 后最关键的一步是升级 Pip。这里必须强调永远不要用pip install --upgrade pip而要用py -3 -m pip install --upgrade pip。原因如下pip install --upgrade pip会尝试用当前默认的pip命令来升级自己。如果这个pip命令指向的是旧版本 Python 的 Pip那么升级后的 Pip 会被安装到旧版本的site-packages里对新版本 Python 完全无效。py -3 -m pip则明确告诉系统“请用最新版的 Python 3.x 解释器去运行它自带的pip模块”。这样升级操作就发生在新 Python 的上下文中保证了 Pip 的“宿主一致性”。如果遇到权限错误PermissionError说明你没有写入C:\Users\YourName\AppData\Local\Programs\Python\Python311\Lib\site-packages的权限。这时不要用--user参数因为--user会把 Pip 安装到C:\Users\YourName\AppData\Roaming\Python\Python311\site-packages这会导致pip命令找不到新 Pip。正确做法是以管理员身份运行命令提示符CMD或 PowerShell再执行上述命令。这是 Windows 系统级权限的正常体现。3.1.3 验证升级是否成功四重校验法单靠pip --version是不够的。我习惯用以下四条命令交叉验证py -3 --version确认 Python 主版本已更新。py -3 -c import sys; print(sys.executable)确认 Python 解释器路径指向新安装目录。py -3 -m pip --version确认 Pip 是由新 Python 解释器加载的。where pip确认pip.exe文件存在于新 Python 的Scripts目录下。只有这四条命令全部指向同一个新版本如 3.12.1才算真正升级成功。任何一条不一致都意味着 PATH、符号链接或安装过程出现了偏差需要回头排查。3.2 macOSHomebrew 是你的“瑞士军刀”但必须理解它的“包管理哲学”macOS 没有像 Windows 那样统一的官方安装器生态也没有像 Linux 那样原生的apt/dnf。Homebrew 的出现正是为了解决这个真空。它不是一个简单的“软件下载站”而是一个遵循 Unix 哲学的、基于源码编译或预编译二进制的包管理系统。理解这一点是用好它的前提。3.2.1 为什么 Homebrew 是 macOS 上升级 Python 的首选版本隔离Homebrew 将所有软件安装在/opt/homebrewApple Silicon或/usr/localIntel下与系统/usr/bin完全隔离。这意味着你升级 Homebrew 的 Python绝不会影响 macOS 系统自带的任何东西尽管系统 Python 已废弃但保持隔离仍是最佳实践。依赖透明brew install python会自动安装openssl,sqlite3,xz等 Python 编译和运行所必需的底层库。这些库的版本是经过 Homebrew 团队严格测试的能最大程度避免“DLL Hell”动态链接库地狱。升级原子性brew upgrade python是一个原子操作。它会先下载新版本的二进制包然后原子性地替换旧文件最后更新符号链接。整个过程不会出现“一半新一半旧”的中间状态。实操心得我从不在 macOS 上用curl https://bootstrap.pypa.io/get-pip.py | python这种方式安装 Pip。因为这种方式绕过了 Homebrew 的包管理Pip 会被安装到系统 Python 的site-packages里导致brew upgrade python后Pip 就“消失”了。Homebrew 安装的 Python其 Pip 是随 Python 一起打包、一起升级的这是最省心、最可靠的模式。3.2.2 升级 Pip 的“无感”操作brew upgrade python已经完成了 90%这是很多新手不知道的关键点当你执行brew upgrade python时Homebrew 不仅升级了 Python 解释器同时也升级了与之绑定的 Pip、setuptools 和 wheel。你不需要、也不应该再单独执行python3 -m pip install --upgrade pip。为什么因为 Homebrew 的 Python 包其pip是作为一个“可执行脚本”位于/opt/homebrew/bin/pip3被安装的它内部硬编码了对/opt/homebrew/opt/python3.12/bin/python3.12的调用路径。brew upgrade python会同时更新/opt/homebrew/bin/python3这个符号链接以及/opt/homebrew/bin/pip3这个脚本。所以pip3 --version的输出自然就是新版本 Pip。如果你执意要手动升级 Pip唯一的正当理由是你想跳过 Homebrew 的发布周期立即获得 Pip 的最新补丁比如一个刚发布的安全 hotfix。这时你应该用python3 -m pip install --upgrade pip --force-reinstall并确保python3命令确实指向 Homebrew 的 Python用which python3验证。3.2.3 PATH 的终极掌控.zshrc里的两行魔法macOS Sonoma 默认使用 Zsh。为了让brew安装的命令python3,pip3,brew本身能在任何终端窗口中被找到你必须把 Homebrew 的bin目录加入 PATH。Homebrew 安装完成后它会贴心地告诉你该怎么做但很多人忽略了。对于 Apple Silicon Mac你需要在~/.zshrc文件末尾添加export PATH/opt/homebrew/bin:$PATH对于 Intel Mac则是export PATH/usr/local/bin:$PATH然后执行source ~/.zshrc使其生效。提示export PATH...这行代码必须放在~/.zshrc的最前面或者至少在任何可能修改 PATH 的其他代码比如 pyenv 的初始化代码之前。否则pyenv 的shims目录可能会被放在 PATH 的最前面导致你永远调用不到 Homebrew 的python3。3.3 LinuxUbuntu/Debianapt是你的“系统管家”但要懂得何时放手Linux 发行版的哲学是“稳定压倒一切”。Ubuntu 的apt仓库里的python3包其版本是经过 LTS长期支持周期严格锁定的。例如Ubuntu 22.04 LTS 的python3默认是 3.10它会一直维持到 2027 年。这意味着sudo apt upgrade python3永远不会把你带到 3.11 或 3.12。这是设计使然不是 bug。3.3.1apt升级的适用场景与局限性sudo apt install python3的真正作用是确保你拥有该发行版所支持的、最新的、经过充分测试的 Python 3.x 版本。它适合以下场景你在一台生产服务器上追求极致的稳定性不希望任何未经测试的 Python 版本破坏现有服务。你只需要一个“够用”的 Python 环境来运行apt仓库里的 Python 应用如ansible,salt。你是一个 Linux 系统管理员负责维护数百台服务器需要统一、可审计的软件版本。但它不适合你是一个 Python 开发者需要尝鲜 3.12 的新特性如typing.LiteralString。你需要为不同项目安装互不兼容的 Python 版本如一个项目用 3.9另一个用 3.11。你正在使用pyenv或asdf这样的版本管理器。3.3.2 升级 Pip 的“双轨制”系统级 vs 用户级在 Ubuntu 上pip的安装方式有两种它们服务于完全不同的目的系统级 Pip (/usr/bin/pip3)由python3-pip这个 APT 包提供。它被安装在/usr/bin/pip3其site-packages目录是/usr/lib/python3/dist-packages。这个 Pip 是为系统级 Python 服务的你不应该用它来安装任何你自己的 Python 包。因为sudo pip3 install会把包安装到系统目录这可能导致apt upgrade时发生冲突甚至破坏系统。用户级 Pip (~/.local/bin/pip3)这是推荐给开发者的模式。当你执行python3 -m pip install --upgrade pip --user时Pip 会被安装到~/.local/bin/pip3而所有通过它安装的包都会放在~/.local/lib/python3.10/site-packages。这个目录完全属于你个人apt永远不会动它sudo也永远不需要碰它。实操心得我在所有 Ubuntu 开发机上都执行python3 -m pip install --upgrade pip --user然后在~/.bashrc里添加export PATH$HOME/.local/bin:$PATH。这样pip3命令就永远指向我自己的、可自由升级的 Pip彻底摆脱了apt的束缚。这是一个简单、安全、高效的“破局”方案。3.3.3 验证与调试ls -l是你的显微镜Linux 上的符号链接symlink是理解环境的关键。当你怀疑python3或pip3指向了错误的地方最直接的办法就是用ls -l查看它们的“真身”。ls -l /usr/bin/python3 # 输出可能为/usr/bin/python3 - python3.10 ls -l /usr/bin/pip3 # 输出可能为/usr/bin/pip3 - /usr/bin/python3.10 -m pip这个输出清晰地告诉你pip3命令的本质就是调用python3.10 -m pip。所以如果你apt upgrade python3.10到了 3.10.12pip3就会自动获得新版本的 Pip。但如果apt仓库里根本没有python3.11那么ls -l /usr/bin/python3就永远不会变成- python3.11。这时候你就该考虑pyenv了。4. 常见问题与排查技巧实录那些让我凌晨三点还在敲键盘的“经典故障”再完美的流程也会遇到意外。下面这些是我过去十年里在 Slack、Teams、邮件和电话会议中被问得最多、最让人抓狂的问题。我把它们整理成一张“速查表”并附上我亲测有效的、非教科书式的解决方案。问题现象根本原因我的排查步骤终极解决方案pip: command not foundpip可执行文件不在 PATH 中或根本未安装。1. 运行python3 -m pip --version。如果成功说明 Pip 存在只是pip命令没配好。2. 运行which pip。如果无输出说明 PATH 里没有pip的路径。3. 运行ls -l $(python3 -c import site; print(site.getusersitepackages().replace(site-packages, bin)))查看pip是否在用户级bin目录下。如果python3 -m pip成功就执行python3 -m pip install --upgrade pip --user然后将~/.local/bin加入 PATH。如果python3 -m pip失败说明 Pip 根本没装需下载get-pip.py并用python3 get-pip.py安装。ERROR: Could not install packages due to an EnvironmentError: [Errno 13] Permission denied试图将包安装到系统级site-packages但当前用户没有写入权限。1. 运行python3 -c import site; print(site.getsitepackages())查看系统级路径。2. 运行python3 -c import site; print(site.getusersitepackages())查看用户级路径。永远不要用sudo pip install。改用python3 -m pip install --user package_name。这是 Linux/macOS 的金科玉律。WARNING: pip is being invoked by an old script wrapper...你正在用一个旧的、由旧版 Pip 创建的pip脚本而 Pip 已升级。运行which pip找到pip脚本的位置。然后运行head -n 1 $(which pip)查看它第一行的 shebang如#!/usr/bin/python3.8。删除旧的pip脚本rm $(which pip)然后用python3 -m pip install --upgrade pip重新生成新的、匹配当前 Python 的脚本。Could not fetch URL https://pypi.org/simple/...: There was a problem confirming the ssl certificate系统缺少可信的根证书或 Python 的证书存储未更新。1. 在浏览器中访问https://pypi.org确认网络和证书没问题。2. 运行python3 -c import ssl; print(ssl.get_default_verify_paths())查看 Python 信任的证书路径。在 Ubuntu 上运行sudo apt install ca-certificates在 macOS 上运行/opt/homebrew/bin/brew install ca-certificates然后python3 -m pip install --upgrade pip。如果公司有私有 CA需将公司根证书.pem文件放入 Python 的certifi证书包中。ModuleNotFoundError: No module named pipPython 解释器里没有安装pip模块常见于最小化安装的 Linux 系统或某些 Docker 镜像。运行python3 -c import sys; print(sys.path)确认site-packages路径存在且可读。下载get-pip.pycurl https://bootstrap.pypa.io/get-pip.py -o get-pip.py然后运行python3 get-pip.py。这是最通用、最可靠的“急救”方案。注意上面表格中的“终极解决方案”都是我在线上环境反复验证过的。例如“永远不要用sudo pip install”这条源于我曾经在一个客户的生产数据库服务器上因为执行了sudo pip install psycopg2-binary导致系统apt的python3-distutils包被破坏进而让整个apt包管理器瘫痪了 6 小时。这个教训让我把这条规则写进了公司所有 Python 开发者的入职培训手册。5. 超越升级构建一个可持续演进的 Python 环境升级 Python 和 Pip不是终点而是一个健康 Python 开发环境的起点。一个真正专业的开发者会把环境管理当作一项基础设施来建设。下面是我认为每个 Python 工程师都应该掌握的、超越基础升级的三项核心能力。5.1 版本管理pyenv是你的“时间机器”当你的工作流涉及多个项目而每个项目又要求不同的 Python 版本时pyenv就成了不可或缺的工具。它的工作原理非常优雅它在你的 shell 中插入一个shim层当你输入python时pyenv会先检查当前目录下是否有.python-version文件如果有就自动调用该文件指定的 Python 版本如果没有就向上级目录递归查找直到找到~/.pyenv/version这个全局默认版本。安装pyenv后你可以轻松实现# 全局设置为 3.11 pyenv global 3.11.7 # 进入一个项目目录局部设置为 3.9 cd ~/my-old-project pyenv local 3.9.18 # 此时在这个目录下python --version 就会输出 3.9.18 # 而在其他目录它还是 3.11.7提示pyenv安装 Python 是从源码编译的速度较慢。你可以用pyenv install --list查看所有可用版本然后用pyenv install 3.12.1安装。安装完成后pyenv versions会列出所有已安装版本pyenv shell 3.12.1可以临时切换当前 shell 的 Python 版本。5.2 依赖隔离venv是你的“无菌实验室”pip install --user解决了“用户级”和“系统级”的冲突但没解决“项目A”和“项目B”的依赖冲突。项目A 需要Django 4.2项目B 需要Django 5.0它们不可能共存于同一个site-packages目录。venv虚拟环境就是为此而生。创建一个虚拟环境本质是创建一个独立的、轻量级的 Python 解释器副本它拥有自己完全独立的site-packages目录。命令极其简单# 创建一个名为 venv 的虚拟环境 python3 -m venv venv # 激活它Linux/macOS source venv/bin/activate # 激活它Windows venv\Scripts\activate.bat # 此时你的终端提示符会变成 (venv) $并且 pip install 的所有包都只在这个 venv 里生效。实操心得我所有的 Python 项目都强制要求有一个requirements.txt文件。在虚拟环境中用pip freeze requirements.txt生成它。部署时只需python3 -m venv venv source venv/bin/activate pip install -r requirements.txt就能完美复现开发环境。这是 CI/CD 流水线稳定运行的基石。5.3 包管理现代化拥抱pip-tools和poetrypip本身是一个强大的工具但它缺乏对“依赖解析”的深度支持。pip install django会安装 Django 及其所有依赖但pip freeze输出的requirements.txt是一个“扁平列表”它不区分哪些是直接依赖你明确写的django哪些是间接依赖django依赖的sqlparse。这导致了“依赖漂移”问题今天pip freeze输出的sqlparse0.4.4明天pip install flask可能会把sqlparse升级到0.4.5而你完全不知情。pip-tools就是为了解决这个问题。它引入了requirements.in声明直接依赖和requirements.txt由pip-compile自动生成的、锁定所有间接依赖的精确版本列表的概念。# 在 requirements.in 里写django4.2,5.0 # 然后运行 pip-compile requirements.in # 它会生成一个包含 django、sqlparse、asgiref 等所有依赖及其精确版本的 requirements.txt而poetry则更进一步它是一个集“依赖管理”、“虚拟环境管理”、“项目打包”、“发布”于一体的现代工具。它用pyproject.toml文件替代了requirements.txt和setup.py让整个 Python 项目的元数据管理变得前所未有的清晰和声明式。个人体会我从 2020 年开始在所有新项目中全面转向poetry。它让我第一次感觉到Python 的包管理终于有了和 Node.js 的npm、Rust 的cargo同等的成熟度和体验。虽然学习曲线略陡但节省下来的时间和避免的“依赖地狱”早已百倍偿还。如果你还在用裸pip我强烈建议你花一个下午跟着poetry的官方教程走一遍。它会改变你对 Python 工程化的认知。