1. 为什么 2026 年了,我还要劝你重新学一遍 pip
先说个直白结论:pip 是 Python 生态里最容易被低估、也最值得花一小时彻底搞懂的工具。很多人写 Python 写到第三年,pip install用得比print还熟练,但真遇到依赖冲突、安装卡死、环境装错、公司内网装不了包这类问题,还是会懵。2026 年了,Python 生态的工具链已经发展得非常成熟,uv、poetry、pdm这些新秀把体验做得确实漂亮,但绝大多数项目、绝大多数 CI 脚本、绝大多数生产环境,用的依然是 pip。不夸张地说,pip 依然是 Python 包管理的"底层操作系统",其他工具要么是它的封装,要么只是换了层皮。
这篇文章不是 pip 文档的翻译,而是我这些年在一线项目中踩坑踩出来的经验总结。适合三类人:刚学 Python 没多久、想搞清楚 pip 原理的新手;被各种依赖问题折磨过、想系统梳理一遍的中级开发者;以及需要在团队里负责环境治理、镜像源配置、依赖锁定的技术负责人。文章里的每一段命令、每一个配置、每一处坑,都是我实际跑过的,照着抄就行,但更建议你看完背后的为什么——只有知道原理,下次遇到新坑才不慌。
先说一个 2026 年的新变化:Python 官方已经把ensurepip和自己的托管源做了整合,新版本的解释器在安装时基本上会自带一个可用的 pip,不再像早些年那样需要手动get-pip.py。但版本自带的 pip 往往偏旧,所以装好 Python 后第一件事依然是升级 pip。这个动作看起来简单,但里面有个小的坑:在部分 Linux 发行版里,直接pip install --upgrade pip会提示"externally-managed-environment",这是系统在保护自己的包管理器,不是报错,解决方案后面会专门讲。
另外提醒一个概念:pip 是 Python 的包安装器,而包管理不只是"安装"这一个动作。它覆盖了依赖解析、版本锁定、卸载、缓存、验证签名、镜像源切换、虚拟环境隔离、构建分发这一整条链路。本文会把这套链路完整走一遍,保证你读完能独立解决 90% 的日常包管理问题。
2. pip 的核心机制:它到底是怎么把一个包装进你环境的
2.1 pip、PyPI 与 wheel:包管理的三驾马车
很多人把 pip 和 PyPI 混为一谈,这是第一个认知误区。严格来说:pip 是客户端工具,PyPI(Python Package Index)是官方包索引仓库,wheel 是打包格式。三者的关系可以类比成手机应用商店:PyPI 是应用商店服务器,pip 是手机上的应用商店 App,wheel 则相当于商店里下载下来直接能运行的安装包文件。
一天 当你执行pip install requests的时候,背后实际发生了几件事:pip 先根据当前 Python 版本、操作系统、CPU 架构,向 PyPI 发起请求,获取requests包的元数据;然后进入依赖解析阶段,找出requests依赖了哪些其他包(比如certifi、idna、charset-normalizer和urllib3),确认这些依赖彼此之间没有版本冲突;接着从索引仓库下载合适的 wheel 文件;最后解压到当前环境的site-packages目录,并把可执行脚本放入bin(Windows 下是Scripts)目录。
早期 pip 还会花大量时间做分辨率解析,因为要处理复杂的版本依赖图,速度慢且容易出错。2026 年的 pip 使用了全新的 resolver(依赖解析器),从旧版的"先安装再检查冲突"改为"先解析再执行安装",虽然首次安装会稍微慢一点,但能大幅降低装到一半才发现版本冲突的尴尬情况。这一点比较重要,后面在排查依赖问题时还会提到。
2.2 site-packages、dist-info 与 RECORD:包的"户口本"
装好的包放在哪里?这可能是新手最关心的问题之一。正常情况下,全局环境下的包放在 Python 安装目录的Lib/site-packages(Windows)或lib/python3.x/site-packages(Linux/macOS)下。虚拟环境里则放在虚拟环境自己的目录里。
每个安装的包旁边会多出一个.dist-info文件夹,乍看像个杂物间,实际是包的"户口本"。里面有METADATA记录包的元信息(名称、版本、作者、依赖关系),有RECORD列出所有安装文件的路径和哈希值,方便卸载时精确清理,还有top_level.txt说明包导出哪些顶层模块。这些信息对 pip 的卸载和升级至关重要。如果你手动删了某个包的文件,但没删.dist-info,下次pip uninstall就会报"文件不存在"或者卸载不干净,就是这个原因。
pip show 包名可以查看一个包的详细信息,比如安装位置、依赖哪些其他包、被哪些包依赖。排查问题时这个命令特别好用。我遇到过一种情况:某个包明明没装,但代码里能import成功,后来用pip show一查,发现是另一个包把它作为依赖带进来了。这种"隐式安装"在旧版 resolver 下很常见,新版已经改进,但历史的坑还是存在。
2.3 pip 的索引源与版本选择逻辑
默认情况下,pip 从 PyPI 官方源拉包。但官方源在国外,国内直连速度不稳定。版本选择方面,pip 遵循PEP 440版本规范,规则大致是:正常版本号1.2.3优先于预发布版本1.3.0rc1、1.3.0b1、1.3.0a1;默认情况下 pip 不会主动选择预发布版本,除非你显式指定。
pip install 包名会安装满足当前环境的最新的稳定版;pip install 包名==1.2.3安装指定版本;pip install "包名>=1.2,<2.0"安装某个范围。后者在 requirements 文件里非常常见,团队协同开发时,这种约束既能保证使用到的特性存在,又避免了大版本升级带来的破坏性变更。
还要知道一个实用选项:pip install 包名 --pre允许安装预发布版。当你需要提前体验某个库的新功能时可以用,但要清楚这可能导致不稳定。我建议在正式环境不要加这个参数。
3. 2026 实用版:pip 的日常高频操作与提速配置
3.1 安装、升级、卸载:准确说清楚每个参数
先列一个高频命令速查表,随后逐一解释关键参数:
| 操作 | 命令 | 说明 |
|---|---|---|
| 安装包 | pip install requests | 安装最新版 |
| 安装指定版本 | pip install requests==2.32.0 | 锁定版本 |
| 安装范围版本 | pip install "requests>=2.28,<3" | 范围约束 |
| 升级包 | pip install --upgrade requests | 等价于pip install -U requests |
| 卸载包 | pip uninstall requests | 卸载同时移除依赖记录 |
| 查看包信息 | pip show requests | 显示版本、依赖、位置 |
| 列出所有包 | pip list | 查看已安装清单 |
| 检查依赖冲突 | pip check | 检查当前环境依赖是否完好 |
| 下载但不安装 | pip download requests -d ./pkg | 离线安装前准备 |
重点说pip uninstall -y:加-y参数可以在卸载时跳过二次确认,适合批量操作。而pip install --no-deps指示 pip 只安装目标包本身,不安装其依赖。这个参数在离线环境或者验包时很有用,但日常有序环境不建议使用,容易导致依赖缺失。
还有一个容易忽略但非常关键的参数:--user。在 Linux/macOS 上,不带虚拟环境且没有 root 权限时,pip install会尝试往全局 site-packages 写文件,如果权限不足会报错。加上--user后,包会安装到当前用户目录下的~/.local/lib/python3.x/site-packages,不需要管理员权限。Windows 上则一般不需要用--user。
升级 pip 本身其实有两种方式:python -m pip install --upgrade pip是官方推荐做法。注意一定要用python -m pip而不是直接pip,尤其在机器上有多个 Python 版本时。直接敲pip命令用的是PATH里最先命中的那个解释器,而python -m pip明确了对应当前python命令的解释器,二者可能指向不同的环境和不同的 pip 版本。这个细节在排查"我明明装了包为什么 import 不到"时是第一个要检查的。
3.2 全局配置与镜像源提速
国内网络环境下,从 PyPI 官方源拉取包经常只有几十 KB/s 的下载速度,所以配置国内镜像源基本是每个开发者必做的一步。镜像源本质上就是 PyPI 的同步副本,在 pip 配置里指定一个更快的源地址,下载速度往往能提升几十倍。
2026 年可用的国内镜像源有好几个,比如清华、阿里、腾讯、中科大,都支持 HTTP 和 HTTPS,同步时间短,稳定度高。拿清华源举例:
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple这条命令会把镜像地址写入 pip 的配置文件,之后再安装包就从清华源拉取。配置文件的路径在不同系统上不一样:Linux/macOS 在~/.config/pip/pip.conf(新版)或~/.pip/pip.conf(旧版),Windows 在%APPDATA%\pip\pip.ini。
多镜像源场景下,extra-index-url可以补充额外的源。比如主源用清华,同时从公司内网源拉一些私有包:
[global] index-url = https://pypi.tuna.tsinghua.edu.cn/simple extra-index-url = https://pypi.org/simple trusted-host = pypi.org需要留意的是,trusted-host主要用来跳过某些环境的 HTTPS 证书校验。公开镜像源都支持 HTTPS,一般不需要加这个配置;只有在公司内网用自签名证书时才需要,出于安全考虑,不建议直接信任未知主机。
这里有个细节:pip config命令的--global和--user两个参数。前者写入系统级配置,所有用户生效,需要管理员权限;后者只写入当前用户配置。单机开发用--user就行,避免污染全局。
3.3 缓存管理:省时省力的好习惯与磁盘清理
pip 默认会缓存下载过的 wheel 文件,下次安装同一版本时直接复用,不再重复下载。缓存目录在 Linux/macOS 是~/.cache/pip,Windows 是C:\Users\用户名\AppData\Local\pip\cache。这大概是安装提速最被低估的手段之一。
但缓存也有副作用:磁盘空间逐渐被占满。清理命令是:
pip cache purge查看当前缓存占用的命令是:
pip cache info我经常在批量创建虚拟环境时先手动pip cache把常用包预下载一遍,然后再离线创建环境,速度会有很明显的提升。具体怎么做,后面的离线安装章节会说。
4. 虚拟环境、requirements 与依赖锁定:工程化落地三板斧
4.1 为什么 2026 年仍然推荐 venv,以及它和 conda 的区别
虚拟环境解决的问题很直接:不同项目依赖的包版本可能互相冲突,如果全部装到全局环境,升级一个项目的依赖可能毁掉另一个项目。虚拟环境为每个项目创建一套独立的 Python 解释器目录和 site-packages,达到互不干扰的目的。
Python 官方自带的venv是最轻量的虚拟环境方案,不需要额外安装任何包,创建命令:
python -m venv myenv创建完成后,Linux/macOS 上用source myenv/bin/activate激活,Windows 上用myenv\Scripts\activate。激活后命令行提示符会多出(myenv)前缀,此时pip install装的包全部进入该虚拟环境。
很多老开发者习惯用virtualenv,它是第三方工具,出现得比venv早,支持 Python 2。2026 年的环境下,除非你还在维护老项目,否则建议直接使用官方venv。它内置在标准库中,没有额外依赖,行为更稳定,不需要考虑 virtualenv 和系统 Python 的交互问题。
conda 是另一个生态的解决方案,常用于数据科学场景。它的优势在于不只为 Python 服务,还能管理 C/C++ 库、CUDA 等。但 conda 的包源更新有时滞后于 PyPI,对纯 Python 项目来说,venv + pip 已经足够。两者不是非此即彼的关系,conda 环境里同样可以用 pip 安装 PyPI 独有包。要注意的是,在 conda 环境里谨慎使用pip install安装大量包来替代 conda 的依赖管理,否则容易破坏 conda 的依赖解析一致性。我见过不少数据科学家在处理这两种工具的依赖时吃过亏,后面原生包和 pip 包的混合问题还要再提。
4.2 requirements.txt、requirements-dev.txt 的规范用法
requirements.txt是 Python 项目最为通用的依赖清单文件。常规用法是pip install -r requirements.txt安装清单里的所有包。
写 requirements 文件有几个关键习惯:
第一,锁定版本。不要只写包名,而是把主版本和修订版本都写清楚。比如:
requests==2.32.0 flask==3.0.3 numpy>=1.26,<2.0requests==2.32.0是完全锁死,团队所有人装出来环境一致。numpy>=1.26,<2.0则是对大版本做约束,允许小版本浮动,适合依赖比较大、升级频繁的包。
第二,区分生产依赖和开发依赖。开发环境往往还需要pytest、black、ruff等工具,这些不应该混在生产依赖里。推荐的拆分方式是:requirements.txt只装生产环境需要的包,requirements-dev.txt包含开发工具,并在文件里引用前者:
-r requirements.txt pytest==8.0.0 black==24.3.0第三,准确记录依赖来源。如果环境里有依赖是从本地 wheel 装的,或者来自私有源,需要在文件里体现。一般来说,requirements 文件建议使用从当前环境导出的结果,保证一致性。
导出当前环境全部包的版本,命令是:
pip freeze > requirements.txtpip freeze和pip list都列出已安装包,但 freeze 只列出 pip 管理的包且格式就是 requirements 的标准格式。我们通常用 freeze 输出生成锁定文件,但要注意 freeze 会把当前环境的所有包都列出来,如果你一个虚拟环境只给一个项目用,那是没问题的;如果虚拟环境里混了其他项目的东西,就要小心不要把无关依赖带进去。
4.3 pip-tools 与 pip-compile:依赖锁定的进阶玩法
当一个项目沉淀到了一定规模,直接用requirements.txt会逐渐失控——你锁定了顶层依赖的版本,但传递依赖(间接依赖)的版本并没有被锁定。某天某个传递依赖发了新版本,破坏了兼容性,你的项目可能就神秘地挂了。复制环境还好,真正崩溃的是你希望优雅地升级某个底层依赖的时候。
这时候就可以用pip-tools了。它提供两个核心命令:pip-compile和pip-sync。
pip-compile的作用:你只需要在requirements.in里写顶层依赖和版本约束,它自动解析依赖树,生成完整的锁定文件requirements.txt,把每一层传递依赖的精确版本都固定下来。
# requirements.in requests==2.32.0 flask==3.0.3执行:
pip-compile requirements.in -o requirements.txt生成的 requirements.txt 会带上"由 requests==2.32.0 生成"这样的注释,以及每个包的来源哈希——如果配合--generate-hashes,还能生成 Hash 校验值,加强供应链安全。
pip-sync则根据 requirements.txt 将当前环境调整为与文件完全一致的包版本集合,自动安装缺失包、卸载多余包。这个工具配合 CI/CD 使用特别好,保证流水线环境每次都能精确复现。
我个人的建议是:个人学习项目用普通的 requirements.txt 就够,但正经的团队项目、要对外发布的产品,请务必引入 pip-tools 这类锁定工具。成本很低,但能省掉大量"在我们机器上明明是好的"这类问题。
5. 离线安装、私有源与安全实践:生产环境的硬功夫
5.1 完全离线场景:如何用一台联网机器给内网机器喂包
有些生产环境是不能直接访问公网的。每台服务器都要允许访问 PyPI 吗?办公网络和外网往往有限制,所以运维同学的常规动作是:在一台有网的机器上把需要的包和依赖全部下载成 wheel 文件,再拷到内网机器上离线安装。
下载依赖但不安装的指令:
pip download -r requirements.txt -d ./packages这样./packages目录下会生成所有顶层包以及它们的依赖的 wheel 文件,之后拷贝到内网机器上,执行:
pip install --no-index --find-links=./packages -r requirements.txt--no-index表示不从索引源拉取包,--find-links指定从本地目录找。如果内网机器也要装开发依赖,同样把对应文件放进去就行。
这里要特别提醒一个坑:wheel 文件和平台是强相关的。在 Linux x86_64 上下载的包,不一定能在 Windows 或者 ARM 架构上安装。pip download默认下载匹配当前平台的包,如果目标是不同平台,需要加上--platform、--python-version、--only-binary=:all:等参数来指定目标平台。例如为纯 Python 包跨平台下载:
pip download \ --platform manylinux2014_x86_64 \ --python-version 3.11 \ --only-binary=:all: \ --dest ./linux-packages \ -r requirements.txt这个命令只下载二进制包,如果某个依赖没有对应平台的 wheel,会报错跳过,需要另行处理源码包。还有一种比较省事的方案:在公司内网架设一个 PyPI 私有镜像,用 devpi 或 bandersnatch 做上游缓存。这样内网机器直接用index-url指向内网源,体验和公网一样,同时还能缓存私有包。这是比较推荐的企业级做法。
5.2 pip 安全:哈希校验与供应链攻击防护
说实话 pip 的安全问题在 2025、2026 年被社区越来越多地讨论。PyPI 上出现过不少钓鱼包和抢名包,用很相似的名字诱导开发者安装,实际代码里带着恶意逻辑。防护措施有几个,成本从低到高:
第一,安装前用pip index versions 包名查看包名是否存在,确认拼写正确、没有被抢注。如果看到一个下载量很大的知名包名出现在你的搜索结果里,但包名和你要装的只有一两个字母的差异,就要多加小心。
第二,利用 pip 的哈希校验。pip install支持--require-hashes,要求 requirements 文件里每个包都带--hash值:
requests==2.32.0 \ --hash=sha256:xxxx...这样安装时 pip 会校验下载文件的哈希值,确保跟你预期的一致。用pip-compile --generate-hashes可以自动生成这些哈希值。
第三,尽量使用虚拟环境 + 最小权限原则。不要在系统全局环境里装来源不明的包,也不要随便用 root 跑 pip install。生产环境的依赖尽量从锁定的源获取。在公司里,私有源配好了,就不应该让开发者直连公网 PyPI,从源头减少暴露面。
5.3 与系统的分权之争:理解 PEP 668 的 externally-managed-environment
装 Python 包时,在较新版本的 Linux 发行版上常会遇到这样的报错:
error: externally-managed-environment This environment is externally managed通俗地说,这是发行版在告诉你:"你的 Python 环境被我(系统包管理器)管着,你直接用 pip 装可能会和系统包冲突,我不允许。"
这个机制来自 PEP 668。从 Debian 12、Ubuntu 23.04 等版本开始,系统 Python 环境都被标记为 externally managed,直接pip install会报错。解决方案很简单:用虚拟环境。在 venv 里装包没有这个限制。如果确实需要在系统环境中装,可以加--break-system-packages参数强行安装,但这是以放弃系统保护为代价的,不太建议用,尤其是生产环境。我对这个报错的理解:它不是 bug,而是系统的善意提醒。学会用虚拟环境,这个问题就自然不存在了。
6. 搭建 pip 私服:企业内网的统一包源方案
当团队规模扩大、项目数量增多后,只靠公网镜像 + 本地 wheel 拷贝的方式会有一些不便利。每次依赖变更都要手动下载再分发,私有的业务包也没地方放,于是很多团队会搭建自己的 pip 私服。这个环节放在后面讲,因为它是环境治理的进阶需求。
常见方案是 devpi 和 bandersnatch。devpi 类似一个代理层,既缓存上游公网 PyPI 的包,也允许上传私有包,支持多索引、权限管理,在多个包版本里搜索。bandersnatch 则是做 PyPI 全量镜像的,可以定期同步完整仓库到内网。对于需要完全隔离公网的场景,用 bandersnatch 做一次性全量同步更彻底;对于日常开发,devpi 更轻便。
搭建 devpi 的大致步骤(在 Linux 服务器上):
# 安装 devpi-server 和 devpi-client pip install devpi-server devpi-client # 初始化并启动服务 devpi-init --serverdir /data/devpi devpi-server --serverdir /data/devpi --port 3141 --host 0.0.0.0然后在开发者机器上配置:
# 先指向自己的私服 pip config set global.index-url http://your-server:3141/root/pypi/+simple/ pip config set global.trusted-host your-server开发者第一次访问时,devpi 会在后台把没有缓存的包从上游源拉取并缓存下来,后续直接命中缓存。私有包则通过devpi upload上传到独立索引里。
这个方案的好处很明显:依赖解析、下载速度、私有包托管都能在内网闭环完成。运维同学也不用再手工拷贝 wheel 文件。我在某中型团队搭过一次,前后用时一个下午,但之后半年再没听到过"装不上包"的投诉。
7. 高频问题排查实录:那些年 pip 给我挖的坑
7.1 装好了包却 import 不到
这个问题的排查思路是固定的:先确认你执行pip install的解释器和执行python代码的解释器是不是同一个。在命令行分别执行:
python -m pip --version python --version which python # 或 where python(Windows)如果 pip 和 python 不一致,比如 pip 属于 Python 3.11 而当前python指向 3.12,那装到 3.11 的包当然 import 不到。解决方案:用python -m pip install 包名替代裸pip install。**「裸 pip 命令属于 PATH 里排在最前面的那个 Python,而 python -m pip 属于当前 python 命令那个 Python」,这个区别是所有环境混乱的根源。
另外检查是否激活了正确的虚拟环境。明明装到了 venv 里,但终端没激活,自然找不到。最后看编辑器用的解释器是不是同一个:VS Code 这类工具允许为每个项目选择不同的解释器,如果选择错误,也会有"能装但 import 不到"的错觉。
7.2 安装时提示"Could not find a version that satisfies the requirement"
这类报错通常有几个来源:
一是包名拼写错误,或者这个包确实不在当前源里。先确认包名拼写,再用pip index versions 包名查看当前源有哪些版本,顺便确认源是不是配置错了。
二是版本冲突。新 resolver 上线后,pip 会在安装前生成依赖图,如果 A 包要求C>=1.0,而 B 包要求C<1.0,就会报"无法找到满足要求的版本"。此时需要用pip check查看冲突详情,或者用pip install 包名 --dry-run先模拟安装,看看 resolver 报什么错误。
三是 Python 版本或平台不兼容。有些包只支持特定 Python 大版本,比如某个包最新版要求 Python >= 3.10,你用的是 3.8,pip 就会提示找不到合适的版本,即使包在源里确确实实存在。解决办法是升级 Python,或者安装旧版包:pip install 包名==旧版本号。
排查这些报错,我建议养成一个习惯:先做pip install ... --dry-run,这个参数不会真正安装东西,但会打印解析日志,能看出 pip 在依赖解析环节具体卡在哪里。少数情况它能直接给出"which requires X"这样的信息,省去大量盲试。
7.3 国内网络下载慢或者超时
配置镜像源是第一选择,参考前面 3.2 节。如果配了镜像源仍然慢,可以调整超时和重试参数:
pip install 包名 \ --timeout 60 \ --retries 3--timeout单位是秒,指单个连接的超时时间;--retries是失败重试次数。内网代理环境下还可以设置 HTTP 代理:
export HTTPS_PROXY=http://your-proxy:port export HTTP_PROXY=http://your-proxy:port注意一点:镜像源有时同步不够及时,刚发版的新包在镜像源里可能还没有,此时用--index-url https://pypi.org/simple临时指定官方源安装,能解决问题。
7.4 pip 版本过低导致的兼容性问题
老版本 pip 对依赖解析的能力比较弱,也不支持新格式的 wheel 元数据。如果你发现某些新包装不上、报奇怪的元数据错误,首先升级 pip:
python -m pip install --upgrade pip一般情况下,升级完 pip 后很多关于"metadata generation failed"或者"package metadata is invalid"的报错都会消失。2026 年的 pip 支持 Python 3.8 及以上版本,老旧的 Python 2 环境(如果还有人维护)建议用旧版 pip,不要强行升级到新版,因为新版不再兼容 Python 2。
7.5 卸载不干净或重装后行为异常
如果发现某次重装后包的行为和预期不符,优先考虑缓存导致的"看起来装了新版,实际上用了旧 wheel"的情况。可以先pip cache purge清理缓存,再重装。如果某个包的文件被手动改动过,pip install --force-reinstall 包名可以强制重装,覆盖已存在的文件。
7.6 权限不足:permission denied
Linux/macOS 上常见的报错是试图往系统目录写文件而没有 root 权限。优先方案是使用虚拟环境,其次加--user,最后才是 sudo。我强烈不建议 sudo pip install,因为这样会让系统全局 site-packages 混乱,且容易覆盖系统包,后续升级系统组件时引发连锁反应。
8. 实践心得:一套我自己的 pip 工作流
最后分享我自己多年用下来的工作流,不追求华丽,但稳定、可复制,供你参考。
日常开发流程是:
- 新建项目目录,创建软性描述
requirements.in(只写顶层依赖); - 创建虚拟环境:
python -m venv .venv; - 激活并升级 pip:
python -m pip install -U pip; - 用
pip-compile requirements.in生成锁定的 requirements.txt; - 安装:
pip install -r requirements.txt; - 提交代码时把 requirements.in 和 requirements.txt 一并提交,其他人直接
pip install -r requirements.txt复现。
每次依赖有变动,改 requirements.in,重新跑 pip-compile,保证锁定文件随时可复现。这种流程用起来后,"环境不一致"的问题几乎绝迹。
做模块化项目,尤其是发布到 PyPI 的库时,我用的打包工具是build。构建命令:
python -m build它会生成 sdist 和 wheel 到dist/目录。之后用twine upload dist/*发布。构建和发布要注意pyproject.toml的配置:requires-python要如实填写,dependencies列表里写清楚运行时依赖,这些信息最终会进入包的 METADATA,被 pip 在安装时读取。
最后再分享一个小技巧:给 pip 启用补全。在 bash 或 zsh 里运行pip completion --bash能生成补全脚本,帮你自动提示命令和参数,虽然不直接解决包管理问题,但能省不少事。
2026 年的 Python 生态里,工具链越来越繁荣,但 pip 依然是根基。把它的原理、常用操作、坑点捋一遍,后面不管换什么工具,理解底层逻辑就不会慌。希望这份教程对你有用。