惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

小众软件
小众软件
IT之家
IT之家
博客园 - 聂微东
www.infosecurity-magazine.com
www.infosecurity-magazine.com
P
Privacy International News Feed
人人都是产品经理
人人都是产品经理
PCI Perspectives
PCI Perspectives
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 叶小钗
V
Vulnerabilities – Threatpost
美团技术团队
S
Secure Thoughts
N
News | PayPal Newsroom
L
LINUX DO - 最新话题
腾讯CDC
Application and Cybersecurity Blog
Application and Cybersecurity Blog
雷峰网
雷峰网
B
Blog
MyScale Blog
MyScale Blog
T
The Blog of Author Tim Ferriss
TaoSecurity Blog
TaoSecurity Blog
N
News and Events Feed by Topic
Blog — PlanetScale
Blog — PlanetScale
C
Check Point Blog
T
Tailwind CSS Blog
月光博客
月光博客
Simon Willison's Weblog
Simon Willison's Weblog
Hacker News: Ask HN
Hacker News: Ask HN
The Last Watchdog
The Last Watchdog
Google DeepMind News
Google DeepMind News
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
MongoDB | Blog
MongoDB | Blog
S
Security @ Cisco Blogs
Jina AI
Jina AI
Engineering at Meta
Engineering at Meta
S
Security Affairs
Forbes - Security
Forbes - Security
P
Palo Alto Networks Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
博客园 - 司徒正美
博客园 - 三生石上(FineUI控件)
T
Tor Project blog
O
OpenAI News
L
Lohrmann on Cybersecurity
Security Archives - TechRepublic
Security Archives - TechRepublic
P
Proofpoint News Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
L
LangChain Blog
B
Blog RSS Feed
H
Hackread – Cybersecurity News, Data Breaches, AI and More

野小新 – 魔帆博客

Mac mini + iPad 随航梦幻联动!零显示器配置指南,iPad 秒变 Mac 主屏幕 | 魔帆博客 解锁iOS侧载自由:使用sideStore轻松搞定ipa签名 | 魔帆博客 Git配置:如何优雅的配置多用户并使用 ssh 密钥验证 | 魔帆博客 Git 合并本地两个不同的 Repo 仓库 | 魔帆博客 Git 提示 fatal: unsafe repository is owned by someone else 错误 | 魔帆博客 安装有 RootMagiskXposedPlay 的 WSA 安卓子系统 | 魔帆博客 Fedora 系统升级 32->34 跨版本升级 | 魔帆博客 教程:如何更新安装 docker-compose V2 和使用 docker switch | 魔帆博客 2022 年 Android 下的安卓浏览器使用指北-Firefox向 | 魔帆博客 Docker WSL1/2 迁移 Linux 发行版目录 | 魔帆博客 Spotify 主题 spicetify-fluent - 微软 win11 风格美化 | 魔帆博客 WSA 安卓子系统 adb 提示 cannot connect the target machine actively refused it 10061 | 魔帆博客 双重验证 Authy 导出所有 TOTP token 和 golang 配置 GOPROXY 解决网络问题 | 魔帆博客 powershll 像 bash 一样为单个命令设置临时环境变量 | 魔帆博客 Linux 教程:Linux 初学者必了解的概念 | 魔帆博客 安卓电池充电保护-智能充电/温控切断(Root方案) | 魔帆博客 备用机养成方案 - Tasker 安卓短信转发到 telegram | 魔帆博客 创建支持安全启动(Secure Boot)的 Arch Linux ISO 安装镜像 | 魔帆博客 MiBand小米手环2/3刷机刷固件刷表盘刷字体指南(iPhone iOS 也支持) | 魔帆博客
Python包管理的血泪史:从混乱到秩序的漫长征 | 魔帆博客
野小新 · 2025-08-26 · via 野小新 – 魔帆博客

不知道各位玩 MCP 或 vibe coding 的时候,是不是发现很多AI工具都需要你电脑装一个叫uv的东西。是不是刚开始看到这玩意儿的时候还以为是紫外线的缩写,心想这跟Python有什么关系?

其实这货是个包管理工具,而且快得飞起。

作为一个从Python 2.7时代就稍微有py交易的老咸鱼,深深地感受到了Python包管理工具的进化史,简直就是一部血泪交织的奋斗史。今天就来聊聊这个话题,给那些刚入坑的小伙伴们讲讲这些年Python包管理都经历了什么。

远古时期:自由散漫的黄金年代

Python早期的时候,那叫一个自由啊!并没有什么强制和可参考的工程结构,你想怎么写就怎么写。一个.py文件就是一个程序,几个.py文件放在一个文件夹里就是一个项目。那时候的程序员们就像是草原上的游牧民族,想在哪里搭帐篷就在哪里搭帐篷。

但是随着项目越来越复杂,这种自由开始变成了一种负担。你有没有经历过打开一个三个月前写的项目,然后发现自己完全不记得这堆文件是怎么组织的?或者接手别人的代码,发现文件结构就像是被台风刮过一样?

pip时代:全局安装的噩梦

后来有了pip,这个工具的出现确实解决了很多问题。但是早期大家都是直接全局安装包,就像是把所有的衣服都塞进一个衣柜里。

pip install requests
pip install flask
pip install django

这一敲,requests等这多个库就被光荣地安装到了你电脑Python的“公共广场”(全局环境)里。项目A用它,项目B也用它,大家共享,其乐融融,看起来很和谐对吧?

灾难很快就来了。

某天,项目A说:“我需要最新版的requests 2.0,新功能酷毙了!”。但项目B是个老古董,哭着喊:“我只认requests 1.0,换了就死给你看!”

你一升级,项目B当场瘫痪;你一降级,项目A立马罢工。这就是传说中的“版本冲突地狱”。你的电脑成了一个火药桶,不知道啥时候就炸了。

这样搞的结果就是,当你有多个项目的时候,版本冲突就来了,然后你就开始怀疑人生了。总不能为了解决这种问题,需要考虑在不同的电脑上跑不同的项目吧(当然,仔细想想也知道这样是想多了,因为根本买不起那么多电脑)

筑起高墙:venv的救赎

为了解决这个“公共广场”的斗殴问题,官方推出了venv(虚拟环境)。它的思路很简单:隔离。与其让大家在广场上打架,不如给每个项目盖一个独立的“私家小院”。

你在项目A的文件夹里创建一个虚拟环境,那A用的所有库都装在这个小院里。项目B也一样,有自己的小院。从此,A和B老死不相往来,你想用什么版本就用什么版本,天下太平。

python -m venv myproject
source myproject/bin/activate  # Windows上是 myproject\Scripts\activate
pip install requests

这简直是划时代的进步!但是新的问题又来了:你把项目A的代码发给朋友小明,小明怎么知道你家小院里都种了哪些“菜”(库)呢?

所以应该怎么记录项目的依赖呢?

requirements.txt时代:手工记账的痛苦

于是大家开始用requirements.txt来记录依赖,只需要如下命令,像拍快照一样,“咔嚓”一声全记录下来。小明拿到你的代码和这个txt文件,只需 pip install -r requirements.txt,就能完美复刻你的开发环境。

pip freeze > requirements.txt

这个文件长这样:

requests==2.25.1
urllib3==1.26.4
certifi==2020.12.5
chardet==4.0.0
idna==2.10

看起来挺好的,但是实际用起来就发现问题了。比如说,你只是想装个requests,但是pip freeze会把requests的所有依赖都写进去。过了几个月你想删掉requests,然后你发现你根本不知道哪些是直接依赖,哪些是间接依赖。删了requests之后,那些孤儿依赖就像是家里的垃圾一样堆在那里。

我曾经看到有个项目的requirements.txt文件有100多行,后来发现其实真正的直接依赖只用了5个包,剩下的95个都是依赖的依赖的依赖…

大一统时代:pyproject.toml 的降临

社区的大佬们也受不了这种混乱了。而且还有配置文件东一个my.ini,西一个pytest.ini,还有刚才说的requirements.txt,简直是“群雄割据”。

于是,pyproject.toml 应运而生——Python官方推出了pyproject.toml标准。

这家伙的野心很大,想把所有项目配置(项目元数据、构建信息、依赖……)都统一到这一个文件里。就像秦始皇统一六国,搞“书同文,车同轨”。如今python生态中绝大多数主流的工具都支持了这个文件。

pyproject.toml里,你可以清晰地声明你的项目直接依赖的是requests。至于requests需要哪些配菜,工具会自动帮你搞定。这样一来,依赖关系清清楚楚,明明白白。

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "my-awesome-project"
version = "0.1.0"
description = "This is my awesome project"
dependencies = [
    "requests>=2.25.0",
    "flask>=2.0.0",
]

但是,它只是个“规范”,是个“宪法”,本身并不提供配套的便捷的工具。你想在开发时装个包,还是得手动激活虚拟环境,然后用pip装,再手动更新pyproject.toml文件…… 特别是pip install -e .这种开发模式(即可编辑模式安装),操作起来就更绕了。想要更新依赖还得手动操作,起来还真是有点麻烦。

工业革命:PoetryPDM 和 uv 闪亮登场

有“宪法”没“行政机构”也不行啊。于是,一群现代化的、高级的项目管理工具应运而生,它们就像是给venvpip套上了一层酷炫的机甲。

  • Poetry: 文艺青年,追求优雅。它严格遵守pyproject.toml规范,帮你管理依赖、打包、发布,一条龙服务。锁定依赖版本非常稳,但有时候有点慢,也比较“固执”。
  • PDM: 务实派,兼容并包。它也用pyproject.toml,但更灵活,甚至能兼容requirements.txt,对老项目迁移很友好。
  • uv性能怪兽,后起之秀。这家伙是Flask框架的大神用Rust语言写的,主打一个字:快! 简直就是包管理界的法拉利。它不仅仅是一个包管理器,还是一个安装器、解析器……功能全面,而且速度快到离谱。安装、锁定依赖的速度比pipPoetry快几个数量级。这就是为什么很多AI工具选择它,因为AI项目的依赖又多又大,速度就是生命!

这些工具,可以看作是 (venv虚拟环境 + pip包安装 + requirements.txt依赖记录) 这个手工作坊模式的“超级升级版”。

现代工作流:让 uv 带你起飞

让我们来看看用uv管理一个项目有多简单:

# 创建新项目
uv init my-project
cd my-project

# 添加依赖
uv add requests
uv add flask --dev  # 开发依赖

# 运行脚本
uv run python main.py

# 同步依赖(类似于 pip install -r requirements.txt)
uv sync

这简单程度简直让人感动得想哭。以前你需要:

  1. 创建虚拟环境:python -m venv venv
  2. 激活虚拟环境:source venv/bin/activate
  3. 安装包:pip install requests
  4. 更新 requirements.txt:pip freeze > requirements.txt
  5. 运行程序:python main.py

现在只需要:

  1. uv add requests
  2. uv run python main.py

uv run会自动在它管理的.venv虚拟环境里执行命令,你连source activate都省了!

两步搞定!而且uv会自动处理虚拟环境,自动更新pyproject.toml,自动生成lock文件。这种感觉就像是从手动挡开到了自动挡,从此解放了双手。

于是你现在的Python项目管理工作流变成了这样:

  1. 项目初始化uv init project-name
  2. 添加依赖uv add package-name
  3. 运行代码uv run python script.py
  4. 管理开发依赖uv add pytest --dev
  5. 项目分享:直接含有把pyproject.tomluv.lock的目录给别人,他们一个uv sync就能复现你的环境

结语

从最早的全局安装到现在的现代化工具,Python的包管理经历了一个从混乱到秩序的过程。虽然过程很痛苦,但是现在回头看看,每一个阶段都有它存在的意义。从最早的全局安装“大锅饭”,到venv的“单间隔离”,再到pyproject.toml的“统一标准”,最后到uv, Poetry这类高级工具带来的“全自动化生产线”。

所以,下次当你在某个AI项目里看到uv时,别再以为是啥黑科技了。它就是那个帮你把凌乱车库整理得井井有条、让你能专心“造车“的超级工具人。对于我们这些爱折腾的宅来说,还有什么比一个更快、更省心的工具更酷的呢?

所以感谢这些工具的开发者们,让我们这些🧑‍💻可以把更多的时间花在写bug上…不对,是写代码上。

好了,不说了,我得去试试用uv给我n年前那个跑起来像拖拉机的老项目重构一下了!