Python 包与环境管理简史:从混乱到优雅

news/2025/9/18 12:18:00/文章来源:https://www.cnblogs.com/aopstudio/p/19098496

自动包管理工具的先驱:easy_install

在一切规范化工具出现之前,Python 的包管理是相当原始的。开发者们需要把第三方库的源码下载下来,手动放到项目目录里。
为了解决自动安装包的问题,easy_install 应运而生。

2004年:easy_install——从 0 到 1 的突破

easy_install 是 Python 包管理的早期自动化解决方案。它可以从 PyPI 自动下载并安装包,极大地简化了获取第三方库的流程。然而,它也存在很多问题:

  • 无法直接卸载:安装容易,卸载却需要手动删除文件。
  • 无依赖管理:它会安装包及其所有依赖,但无法记录或锁定这些依赖的精确版本,导致“依赖地狱”问题依然存在。
  • 容易冲突:多个项目依赖同一个库的不同版本时,easy_install 会陷入困境。

虚拟环境管理+更智能的包管理:virtualenv/venv,pip

2008年:virtualenv——为每个项目建一个虚拟环境

virtualenv 的出现是一个里程碑。它创造性地提出可以为每个项目创建一个独立的、隔离的 Python 虚拟环境。在这个虚拟环境里,你可以随心所欲地安装任何版本的包,而不会影响到系统全局或其他项目。virtualenv 解决了项目间的环境冲突问题,为后续的工具发展奠定了基础。

2011年:pip——更智能的包安装器

pip 作为 easy_install 的替代品逐渐成熟,并最终成为 Python 事实上的标准包安装器。它解决了 easy_install 的诸多痛点:

  • 可以一条命令卸载包
    pip uninstall package_name
    
  • 支持依赖管理:能够自动处理依赖关系。
  • 引入 requirements.txt:通过一个简单的文本文件,你可以记录项目所需的所有依赖及其精确版本。其他人拿到项目后,只需运行
    pip install -r requirements.txt
    
    就能复刻你的开发环境。

2012年:venv——Python内置的虚拟环境工具

venv 是 Python 3.3 引入的一个标准库模块,它提供了 virtualenv 的核心功能,但更加轻量和易用。你可以通过

python -m venv my_env

来创建一个新的虚拟环境,而无需额外安装任何东西。

早期版本的venv相比virtualenv,缺少很多高级特性,因此很多开发人员仍然选择继续使用virtualenv。但随着Python的发展,venv也越来越成熟,目前已经取代了virtualenv成为了虚拟环境的事实性官方标准。

Python解释器版本管理工具:pyenv

pipvirtualenv/venv 解决了“包”和“环境”的问题,但还有一个更底层的问题:Python 解释器本身呢?如果你的电脑系统自带了 Python 2.7,但你的新项目需要 Python 3.10,而另一个维护中的老项目又需要 Python 3.3,怎么办?手动安装、修改 PATH?太麻烦了。

2011年:pyenv——掌控你的 Python 版本

pyenv 的出现,完美地填补了这个空白。它深受 Ruby 社区的 rbenv 启发,其核心思想非常巧妙:它并不真正地“安装”多个 Python 版本,而是在你的 PATH 路径最前面插入一个“垫片”(shim)。当你调用 python 命令时,这个垫片会根据你当前目录或全局的配置,智能地转发给对应版本的 Python 解释器。

通过

pyenv install 3.10.0

命令,你可以轻松安装任意版本的Python(此处示例3.10.0)

通过

pyenv local 3.8.5

命令,你可以为当前目录下的项目指定使用任意版本的Python(此处示例3.8.5)

pyenv 解决了 Python 解释器版本管理的难题,它与 pipvenv 形成了三件套:pyenv 负责管理解释器版本,venv 负责创建隔离环境,pip 负责安装依赖包

一体化工具的尝试:pipenvpoetry

pyenv + virtualenv + pip 虽然强大,但毕竟需要操作三个工具。开发者们开始向往一个能“一键搞定所有”的解决方案。于是,一系列“All-in-One”工具应运而生。

2017年:Pipenv——官方推荐的“希望”

Pipenv 由 Requests 库的作者 Kenneth Reitz 主导开发,并一度被 Python 官方推荐为“用于 Python 项目的官方依赖管理工具”。它试图将 pipvenv 的功能合二为一。

它用 Pipfile和 Pipfile.lock替代了 requirements.txt,提供了更精确的依赖锁定和开发/生产环境的区分。

同时,Pipenv 在早期因为一些性能问题、锁文件生成缓慢以及偶尔的 Bug,社区评价褒贬不一,逐渐失去了一些光环。

Pipenv 本身不管理 Python 解释器版本。所以pyenv在管理不同Python版本的多个项目时仍是必需的工具。(笔者并没有真正使用过pipenv这个工具,根据网上的资料查询得出这个结论,不太确定是不是真的没有这个功能。如果有误,请不吝赐教)

2018年:Poetry——更现代的依赖管理工具

几乎与 Pipenv 同期,Poetry 横空出世,并迅速赢得了大量开发者的心。

它使用 pyproject.toml作为唯一的配置文件,这是 PEP 518 和 PEP 621 所倡导的现代 Python 项目标准,非常简洁和强大。

它的依赖解析算法和锁文件(poetry.lock)生成速度比 Pipenv 更快、更可靠。

另外,它集成了构建、打包和发布到 PyPI 的功能,真正实现了从开发到部署的全流程管理。

pipenv一样,Poetry自身不负责Python版本的管理,仍然需要搭配pyenv来管理Python解释器版本。(笔者并没有真正使用过poetry这个工具,根据网上的资料查询得出这个结论,不太确定是不是真的没有这个功能。如果有误,请不吝赐教)

另一条路:科学计算领域的王者——Conda

在主流 Python 社区为 pipvirtualenv 演进时,科学计算领域走出了另一条完全不同的道路。

2012年:Conda——安装依赖、Python版本管理全包了

Anaconda是数据科学领域发展出的包管理+Python版本管理工具。而且它管理的不仅仅是 Python 包,还可以是R语言等其他语言的软件包。此外,为了提供开箱即用的机制,Anaconda会默认安装许多常用的科学计算库,但这也导致了安装体积过大。因此,又推出了miniconda这个精简版,它只包含了最基本的 Python 和 conda 包管理器。对于Python开发人员来说,更多使用的还是miniconda

Anaconda 在安装时就会自带一个稳定版本的Python,同时还可以通过conda命令直接安装其他版本的Python。

conda create -n myenv python=3.9

这条命令,就可以创建一个包含 Python 3.9 的新环境。

Anaconda可以不依赖pip,直接通过conda install命令安装包。但是conda安装的包版本常常会和pip包冲突,而且PyPI上的很多包都没有conda的版本。

另外,Anaconda使用environment.yml文件来描述环境,这个文件类似于requirements.txt,但更加复杂。在conda中,通过yaml文件来创建环境的命令为:

conda env create -f environment.yml -n 环境名

但说实话能够一次性成功配置环境属于少数情况,一般都会遇到配置太慢、卡死、solving environment failed、PackageNotFound、以及pip爆出的一堆红字。

综合上述原因,在实际的工作流中,人们通常会使用conda创建一个干净的虚拟环境,然后再在这个虚拟环境中使用pip安装其他依赖。

conda create -n myenv python=3.9
conda activate myenv
pip install -r requirements.txt

这也是现在科研领域使用Python的主要方式,绝大多数的Python科研项目都是这样安装依赖的。另外一些老的软件开发项目也会使用这种方式。VSCode对于conda的兼容性也很好,可以直接检测出conda管理的虚拟环境。

速度与整合的终极追求:uv 的时代

时间来到最近,一个名为 uv 的工具横空出世,以其惊人的速度和“大一统”的雄心,再次搅动了整个生态。

2023年:uv ——极速的全面解决方案

uv 由 Astral(Ruff 的开发公司)发布,它是一个用 Rust 编写的、极其快速的 Python 包安装器,最初旨在成为 pip 的直接替代品。
使用

uv pip install package_name

命令,可以极大地提升安装速度。它的速度优势是颠覆性的,将依赖解析和安装的时间从分钟级缩短到了秒级。

uv 的目标远不止于作为一个快速的pip替代品,它正在迅速整合 Python 项目管理的所有核心能力:

  • 项目管理uv init可以快速创建一个包含 pyproject.toml 的项目骨架。
  • 虚拟环境管理uv venv 可以创建和管理虚拟环境。
  • 依赖解析与安装uv adduv removeuv sync 等命令提供了原生的依赖安装体验
  • Python 版本管理:可以通过uv python install命令安装指定的Python版本

现在仅使用uv一个工具就可以实现原本需要pip,venv,pyenv三个工具才能实现的功能。而且相比conda,其更符合Python标准,更加Pythonic。

笔者个人使用经历和体会

前面这段是对历史的梳理,现在来谈一谈我个人使用Python依赖管理工具的经历和体会。

本科毕业后,我先从事了两年NodeJS开发的工作。我个人感觉相对来说NodeJS的版本兼容性应该比Python好不少吧?当时压根就没想到需要不同的NodeJS版本来管理不同项目的问题,用我电脑上安装的NodeJS LTS(长期支持版)运行公司的各个项目都没有遇到兼容性问题。另外,NodeJS中使用npm工具管理项目依赖包,每个项目就是一个独立的环境,也不会出现不同项目之前依赖包冲突的问题。虽然现在也出现了nvm这个管理不同Nodejs版本的工具,但这个工具只是锦上添花,在大多数情况下并不是必需的。

但读研以后开始使用Python,整个情况就变了。不同版本的Python之间兼容性很差,只安装一个Python版本完全无法应对不同的项目,而且pip安装依赖在没有虚拟环境的情况下,默认是到全局环境,无法进行不同项目的环境隔离。

conda是我最早接触的工具,因为我是读研后才开始使用Python的,一开始主要做的也是科研项目。实验室的师兄师姐教我们就是直接用conda,而且基本上所有的科研论文项目的主页上也都是用的conda。venv作为Python官方的虚拟环境解决方案我也了解过,但还是不如conda方便,基本没用过。有了conda以后,项目的版本依赖管理就变得清晰了很多,而且在conda里面想用哪个版本的Python就可以用哪个版本的Python。

conda自带的conda install命令在很多时候安装不到想要的包,而且速度很慢。所以我都是先用conda安装虚拟环境,再用pip安装依赖。

假如我想导出环境给另一台电脑使用该怎么办呢?一开始使用的是这个命令:

pip freeze > requirements.txt

但是这样会存在一个问题,导出的文件包含的是当前虚拟环境中所有的包。有的时候为了图省事,一个conda虚拟环境会给多个项目使用,这样就可能包含很多用不着的包。为了解决这个问题,我又找到了pipreqs这个工具,该工具会扫描当前项目下实际使用的依赖包,并生成对应的requirements.txt文件。

尽管pipreqs工具可以导出实际需要的依赖,但仍然需要手动导出。但使用过npm的我还是觉得不太方便,为什么就不能在安装的同时直接生成一个类似于package.json的文件来管理依赖呢?(其实pyproject.toml文件早已出现,但由于读研期间把绝大多数的精力都放在读论文,想科研点子上,没有时间学习开发工具的使用,一直活在自己的信息茧房里,也就不知道这个东西的存在)

一直到了研究生毕业,再次工作以后,我接触了Dify项目,发现其中使用了一种新的依赖管理工具uv,而且使用pyproject.toml管理项目依赖包。这不就是我梦寐以求的工具吗?再去回看历史,发现原来之前还有poetry,pipenv这些工具。而uv基本上解决了之前所有工具的问题。现在的Python开发人员真是身处一个好时代,有uv这么好的工具。

最后说一下工具的选型。

对于科研人员来说,还是推荐使用conda。尽管其比较笨重,但使用方便,而且也是科研领域的主流解决方案。

但对于开发人员来说,强烈建议转向uv这个现代化工具。这是目前Python依赖管理的集大成者。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/907109.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

qoj853 Flat Organization

SOLUTION FROM WUMIN4 题意 给出一个 \(n\) 个点的带权竞赛图(定向完全图),你可以进行任意次操作,每次操作反转一条边,代价为边权,求使得图强连通的最小代价和与方案,或输出无解。 \(n\le 2000\)。 思路 我们先…

实用指南:Chromium 138 编译指南 macOS 篇:Xcode 与开发工具安装配置(二)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

shell命令中循环执行操作的命令

shell命令中循环执行操作的命令reference: for i in $(seq 1 10000); do echo "Iteration $i" && echo "Iteration $i"; done for i in $(seq 1 10000); do cat /sys/class/net/eth0/carr…

2025年9月中国数据库排行榜:达梦挺进榜眼位,崖山首入前十强

9月墨天轮排行榜解读已出炉!本月前十变动较大,老将突围、新秀崛起,达梦凭借强劲势头跃升至第二位、TiDB排名上升、崖山首次闯入前十,此外还有一些产品表现亮眼!本月墨天轮社区的中国数据库排行榜再起波澜。达梦凭…

基于QEMU模拟器搭建Builtroot下的QT开发环境

基于QEMU模拟器搭建Builtroot下的QT开发环境https://www.cnblogs.com/arnoldlu/p/17250728.html

OpenSSH漏洞修复

前期准备 (先使用Telnet远程连接工具,连接服务器,确保Telnet连接正常,SSH连接后进行漏洞修复升级(防止修复失败,导致远程连接无法连接时,可以通过另一个远程工具连接进行恢复) telnet安装与开启:https://www.…

5个存款技巧,银行员工都在用,你知道几个?

5个存款技巧,银行员工都在用,你知道几个?Posted on 2025-09-18 12:05 lzhdim 阅读(0) 评论(0) 收藏 举报对于普通人来说,辛苦打拼攒下的钱,那都是血汗的结晶。去银行存钱时,咱们往往只知道常规操作,可是银…

windosw 配置arp绑定

windosw 配置arp绑定配置静态arp绑定 netsh interface ipv4 add neighbors "以太网" "192.168.98.233" "aa-bb-cc-dd-ee-01" store=active

trace irqoff

trace irqoffcat /sys/kernel/tracing/available_tracers echo irqsoff > /sys/kernel/tracing/current_tracer cat /sys/kernel/tracing/current_tracer echo 1 > /sys/kernel/tracing/tracing_on cat /sys/ker…

linux proc fs node

linux proc fs node#include <linux/kernel.h> #include <linux/module.h> #include <linux/proc_fs.h> #include <linux/uaccess.h> #include <linux/seq_file.h>#ifdef CONFIG_PROC_F…

2024年最受欢迎的渗透测试工具盘点

本文详细介绍了2024年最受欢迎的渗透测试工具,包括Certipy、BloodHound、Impacket等社区工具和CloudFox、Broken Hill等Bishop Fox自研工具,涵盖网络、云环境、API和LLM安全测试领域。我们最喜爱的渗透测试工具:202…

Unity学习 5.6 FBX

FBX保存了模型和纹理,没有贴图,贴图作为静态资源单独存在 FBX的使用 演示:选择*.fbx文件,直接拖到层级窗口 观察节点图标 选中节点,观察Inspector中的操作按钮select可以focus资源路径贴图路径有的模型需要贴图文…

SEERC 2022 题面简要翻译

A. Append / 附件 你有两个字符串 \(s,t\),同时你还有一个字符串数组,这个数组中的第 \(i\) 个字符串是由 \(i\) 个 \(s\) 拼接而成,现在问最小的 \(p\) 使得 \(t\) 是这个字符串数组的第 \(p\) 个字符串。 \(1 \le…

C++篇(7)string类的模拟搭建

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

【稳定检索、线上线下参会、马理工主办】第十一届建筑、土木与水利工程国际学术会议(ICACHE 2025)

快速见刊,检索稳定! 第十一届建筑、土木与水利工程国际学术会议(ICACHE 2025) 2025 11th International Conference on Architectural, Civil and Hydraulic Engineering (ICACHE 2025) 在这里看会议官网详情 大会…

telnet安装与开启

在 CentOS 中,Telnet 是一种远程登录协议,默认情况下是关闭的。以下是开启 Telnet 服务的步骤。 # 首先检查是否已安装相关软件包 rpm -qa | grep telnet rpm -qa | grep xinetd # 以下命令安装: yum install -y te…

history路由模式下的nginx配置

路由模式 众所周知,浏览器下的单页面应用的路由模式有下面两种: hash 模式和 history 模式。hash 模式通用性好,而且不依赖服务器的配置,省心省力,但是缺点是不够优雅。相比于 hash 模式来说,history 模式则更加…

20250917NOIP#21

20250917NOIP#21 T2 题意: 给定一个 \(n\) 个点的树,点上有一个非负整数点权 \(a_i\),表示这个点需要在操作序列中正好被经过 \(a_i\) 次,一次操作为选择两个顶点 \(u,v\) ,从 \(u\) 经过简单路径走到 \(v\) ,求…

阿里云防刷神器ESA搞活动免费领取

最近使用阿里云的边缘安全加速ESA,防刷、访攻击。 所有套餐支持一键防刷、安全事件分析、频次控制等。 最近搞活动,可以不限次数领取基础版代金券,免费领取链接:http://s.tb.cn/e6.0Fu67m测速效果

报错TypeError: Unknown file extension .ts - broky

当出现这个TypeError: Unknown file extension ".ts"这个报错的时候,可以看看package.json里没有是不是有"type": "module"这个字段,有的话需要去掉