ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Python虚拟环境venv完整指南:创建、依赖管理与IDE集成排错

Python虚拟环境venv完整指南:创建、依赖管理与IDE集成排错 写这篇的时候手头正好有个项目踩了虚拟环境的坑干脆把这几年用 venv 的经验一次性整理出来。无论你是刚装完 Python 准备写第一个脚本还是已经在 PyCharm、VSCode 里被解释器路径搞到头大这篇指南都值得花十分钟看完。先说清楚这篇东西能解决什么问题它会讲明白虚拟环境到底是什么、为什么每个 Python 项目都应该建一个、venv 和其他方案怎么选、从创建到依赖管理再到工程迁移的完整操作以及我实际工作中遇到过的一堆报错和排查思路。看完你就知道那些.venv\Scripts\python.exe后面带一串看不懂报错的日子基本到头了。1. 虚拟环境不是玄学是 Python 项目的安全气囊1.1 没有虚拟环境时依赖冲突有多痛很多人刚接触 Python 时都是直接pip install xxx装完就用完全没意识到全局环境这潭水有多浑。等到第二个项目需要某个库的旧版本而第一个项目用的新版本接口全变了这时候你才明白什么叫牵一发动全身。更麻烦的是系统自带的 Python 往往被操作系统的包管理工具依赖着你随手pip install一个版本不对的库可能连系统工具都跟着罢工。我见过最典型的场景项目 A 用了requests 2.20项目 B 因为接口变化非要requests 2.31两个项目同时跑在一台机器上。你升级A 挂掉你降级B 报错。最后只能靠注释代码、临时卸载安装来凑合每次切项目都是一场赌博。虚拟环境解决的就是这个核心痛点为每个项目准备一套完全独立的 Python 运行空间。这个空间里可以装任意版本的第三方库互相之间隔着墙谁也别想影响谁。你可以把虚拟环境理解成给每个项目开了一个独立的“小房间”房间里放着自己版本的 Python 解释器、pip 工具和所有依赖库房门一关外面再怎么折腾都跟你没关系。1.2 虚拟环境的运行原理为什么它这么轻量很多人以为虚拟环境是把整个 Python 解释器复制一份其实不是。venv 采用的是“链接 覆盖”的思路它只复制或链接解释器的可执行文件再单独维护一个 site-packages 目录这样创建速度极快占用的磁盘空间也非常小。Python 解释器在启动时会按照sys.path的顺序查找模块虚拟环境通过修改这个路径优先级让自己目录下的site-packages排在系统全局的site-packages前面。这样一来你在虚拟环境里import的包永远是环境里的那份而不是全局的那份。在 Windows 上激活虚拟环境其实就是调用Scripts\activate.bat它本质上是设置了一堆环境变量其中最重要的就是PATH把.venv\Scripts插到最前面。这样你在命令行输入python或pip时系统优先找到的是虚拟环境里的程序。在 Linux 和 macOS 上逻辑一样只是激活脚本变成了bin/activate。理解了这个原理后面排查各种诡异报错就容易多了大部分问题都出在“解释器没走对路径”。1.3 venv、virtualenv、conda、pipenv到底用哪个每个工具刚入门的同学都会在这几个名字之间反复横跳。先说结论普通 Python 开发venv 完全够用涉及数据科学多版本 Python 切换conda 是真方便virtualenv 是 venv 的前身没必要再单独装pipenv 和 poetry 属于进阶选择可以后面再接触。用表格看得更清楚工具创建命令是否自带特点venvpython -m venv .venvPython 3.3 自带轻量、简单、无额外依赖virtualenvvirtualenv .venv需 pip 安装支持 Python 2速度稍慢condaconda create -n env_name python3.10需安装 Anaconda/Miniforge可管理 Python 版本本身适合科学计算pipenvpipenv install需 pip 安装同时管理依赖和虚拟环境适合项目管理如果你的项目主要用普通第三方库比如requests、flask、djangovenv 是最好的选择。它不需要额外安装工具Python 装好就能用。Conda 更适合那种对 Python 版本有严格要求的场景因为它可以直接创建不同 Python 版本的环境但随之而来的是体积很大一个基础环境动辄几个 G。我个人的习惯是爬虫、Web 项目用 venv做数据分析或需要切换 Python 小版本时用 conda。2. 从零到一venv 创建与激活的完整实操2.1 创建虚拟环境一行命令的细节先确认你的 Python 已经正确安装并且加入了系统 PATH。在命令行里输入python --version能看到版本号说明解释器没问题接着就能干活了。创建虚拟环境的命令非常简单python -m venv .venv.venv是环境目录名这是社区最常见也最推荐的命名。用venv或者env也行但.venv有个好处以点开头在 Linux 下输入ls默认不显示不会污染你的项目文件列表。VSCode 和 PyCharm 默认也都会优先识别这个目录名省去很多配置的麻烦。创建完成后项目下会出现一个.venv目录。在 Windows 上里面有Scripts子目录存放python.exe、activate.bat和pip.exe在 Linux 和 macOS 上则是bin目录存放python3、pip和activate脚本。两边还有共用的Lib或lib目录里面是site-packages这就是以后第三方库的家。注意创建的目录名一旦定了尽量不要中途改名或移动位置否则里面的一些硬编码路径会失效你会在激活时遇到各种神鬼莫测的报错。后面会专门讲这个坑。2.2 激活环境Windows、Linux、macOS 各自的操作系统不同激活的方式也不一样这个必须分清命令打错了神仙也救不了。Windows 的 CMD 里.venv\Scripts\activate.batWindows 的 PowerShell 里.venv\Scripts\Activate.ps1如果 PowerShell 提示“禁止运行脚本”需要先以管理员权限执行一次Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser这是安全策略问题不是环境坏了放行一次之后就不用再管了。Linux 和 macOS 的 bash/zsh 里source .venv/bin/activate激活成功的标志是命令行提示符前面出现了(.venv)字样比如(.venv) C:\Users\你的用户名\project看到这个小括号就说明你已经在虚拟环境里了。这时候执行python或pip用的都是环境里那份。2.3 退出环境与删除环境干完活要退出命令也很简单deactivateWindows 下直接关掉命令行窗口也可以下次重开不再激活即可。这里有个区分deactivate 是退出虚拟环境删除虚拟环境是直接删除那个.venv目录。很多新手会搞混以为退出就是卸载。虚拟环境本质上就是一个目录不需要“卸载”删掉目录就没了重新建一个也就一条命令的事。所以别怕把环境搞坏大不了rmdir /s .venvWindows或者rm -rf .venvLinux重来一遍成本极低。3. 依赖管理从装包到迁移的完整链路3.1 pip 安装与国内源加速激活虚拟环境后安装第三方库的姿势和之前没有区别还是pip install但注意此时安装的目的地已经变成虚拟环境的site-packages了。你可以验证一下pip show requests如果当前在虚拟环境中输出里有一行Location会指向.venv\Lib\site-packages或.venv/lib/python3.x/site-packages而不是全局的 Python 目录说明安装位置没问题。国内网络环境下直接 pip install 经常慢到怀疑人生或者直接超时用国内镜像源能解决一大半问题。常用的有清华源、阿里源、豆瓣源。我习惯一次性配进全局配置省得每次敲参数pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple这个命令会在用户目录下生成一个 pip.iniWindows或 pip.confLinux之后所有的 pip install 默认走清华源速度从几十 KB 直接跳到几 MB体感提升极其明显。有时候某些冷门库在清华源同步不及时可以临时切换阿里源pip install -i https://mirrors.aliyun.com/pypi/simple/ 某个包名3.2 requirements.txt让依赖可复现项目开发到一定程度依赖会越来越多新同事克隆你的仓库后不可能一个一个手敲pip install。这时候就需要把当前环境里所有依赖导出到文件pip freeze requirements.txt生成的文件长这样Flask3.0.0 requests2.31.0 gunicorn21.2.0等别人拿到这个文件一条命令就能复现你的环境pip install -r requirements.txt这里有一个实操建议pip freeze会把环境里所有包都导出来包括某些依赖的依赖可能非常臃肿。如果你只想记录直接使用的顶层依赖用pipreqs这个工具更合适pip install pipreqs pipreqs ./ --force它会扫描你的源码里实际import了哪些库只导出这些生成的文件更干净。缺点是它靠静态分析有时会漏掉通过字符串方式动态导入的模块需要自己补一下。我的习惯是个人小项目用pip freeze团队协作或发布项目用pipreqs再加手动检查。3.3 虚拟环境的迁移换机器之后怎么恢复“迁移”这个词听起来高大上本质就是三步在新机器上装好 Python把项目代码和 requirements.txt 一起拷过去然后创建新环境并安装依赖。完整流程是这样python -m venv .venv source .venv/bin/activate # Windows 用 .venv\Scripts\activate pip install -r requirements.txt理论上到这步就结束了。但有个很多人忽略的点千万不要把.venv目录本身拷到另一台机器上用。这个目录里的很多路径是写死的比如脚本里的 shebang 路径、配置文件里的绝对路径一旦换机器这些路径全对不上激活时会出现各种诡异问题。我线下见过有人把整个.venv打包发群里问为什么别人解压后用不了原因就在这。正确做法永远是源码 requirements.txt 一起走到了新机器重建环境。一个依赖可能需要的 C 库比如 Pillow 需要 zlib在目标机器上要先装好这些是系统级别的不属于 Python 虚拟环境的管理范围。3.4 解决第三方库安装冲突的几个常见策略装包的时候最怕遇到依赖冲突经典的场景是 A 库要求 numpy 小于 2.0B 库要求 numpy 大于等于 2.1两边互不相让。遇到这种情况直接一条pip install -r requirements.txt装完报错一大串新手很容易崩溃。我的排查思路是分三步走第一步查看当前环境中每个库的版本要求pip list看已装版本pip show 库名看具体信息。第二步优先尝试兼容版本组合比如 numpy 降级到 2.0 之后两个库是否都能跑。第三步如果实在无法兼容分两个环境来用一个专门做数据分析一个专门做服务端通过脚本或配置文件在不同环境间切换。实际操作中大约八成的冲突都可以通过“找一个中间版本”解决剩下的两成需要多环境隔离来处理。这恰恰印证了虚拟环境的价值冲突不可怕可怕的是所有项目挤在一个环境里想隔离都无处下手。4. 与 IDE 的集成PyCharm 与 VSCode 的配置与报错排查4.1 PyCharm 里配置 venv 解释器PyCharm 是目前 Python 开发体验很成熟的一款 IDE配置虚拟环境有两条路创建项目时选择或者项目中途切换。创建新项目时在 New Project 窗口里左侧选好项目目录右侧展开 “Python Interpreter”选择 “Previously configured interpreter”然后点击 “Add Interpreter → Existing environment”弹出的界面里找到.venv\Scripts\python.exeWindows或.venv/bin/pythonLinux/macOS选上即可。项目已经建好但发现解释器没对进入File → Settings → Project → Python Interpreter右上角齿轮 → Add → Existing environment路径指向.venv里的 python 可执行文件。确认后底部会出现当前环境的依赖列表能正常列出来就说明解释器配置成功。这里有个高频报错就是热词里提到的cannot be resolved against python helper roots。出现这个报错背后的原理是PyCharm 在解析项目时会访问配置的 Python 解释器来获取系统模块、辅助包等路径但很多时候它只加载了全局解释器路径没有正确识别虚拟环境的 site-packages于是报错。我实际验证过成功率最高的处理步骤如下打开 PyCharm 右下角的 Python Interpreter 下拉菜单选择 “Interpreter Settings”确认路径正确指向.venv中的 python.exe。进入File → Invalidate Caches / Restart清掉索引缓存让 PyCharm 重新解析环境。如果仍然报错直接删除配置里现有的解释器重新 Add选择 “Existing environment”这次一定要手动浏览到.venv\Scripts\python.exe并勾选 “Make available to all projects”如有此选项。最后一步兜底删除项目下的.idea文件夹它会记录所有 IDE 配置重启 PyCharm重新打开项目重新配解释器。大多数时候走完第三步就能恢复正常第四步只在极端情况下用但确实能解决很多莫名其妙的缓存问题。4.2 VSCode 里选择虚拟环境解释器VSCode 配置虚拟环境的核心逻辑是让 Python 扩展找到.venv里的解释器。打开项目文件夹后按CtrlShiftP打开命令面板输入 “Python: Select Interpreter”弹出的列表中会显示自动扫描到的解释器。如果.venv在项目根目录VSCode 通常会自动识别并列出它。如果不在可以点 “Enter interpreter path”手动浏览到.venv里的 python.exe。选对之后在底部状态栏可以看到 Python 的版本信息比如.venv: python 3.11.5这表示当前已经是虚拟环境解释器了。之后在终端里运行命令时VSCode 默认打开的终端也会自动激活这个环境前提是 Python 扩展开启 integrated terminal 的自动激活功能这个默认是开的。如果在 VSCode 里运行文件时终端显示 “did not find interpreter” 或者导入的库报 ModuleNotFoundError第一件事就是检查状态栏的解释器是不是虚拟环境那个。很多时候是因为先选择了全局解释器导致虚拟环境里装的包全都找不到。这个方向的排查基本能覆盖九成的问题。4.3 PyCharm anaconda3 虚拟环境的报错处理热词里有一条很具体“pycharm 用 anaconda3 虚拟环境中的 python 创建项目报错”。这个问题我帮人排查过不下十次下面说下常见的原因。Anaconda 的虚拟环境和 venv 不同它由 conda 管理Python 解释器和第三方库都放在 Anaconda 安装目录下的envs文件夹里比如C:\Users\用户名\anaconda3\envs\myenv\python.exe。在 PyCharm 里添加这个解释器时很多人直接在文件浏览器里定位不到envs目录因为 PyCharm 默认的文件选择对话框只显示部分目录。正确做法是在 Add Interpreter 界面选择 “Conda Environment”然后点击右侧的 “Existing environment”Interpreter 那里直接填C:\Users\用户名\anaconda3\envs\你的环境名\python.exe。如果下拉框里找不到点击文件夹图标手动浏览到 envs 目录。核心就是确认你用到的 python.exe 一定在 envs 目录下而不是 anaconda3 根目录下的那个 base 环境的 python。另外如果 PyCharm 创建项目后运行时报 “ModuleNotFoundError: No module named numpy” 之类说明解释器选对了但 conda 环境里没装这个包。直接在 PyCharm 底部的 Terminal 里执行conda activate 你的环境名再pip install numpy即可。别在全局环境里装装了也是白装。4.4 Anaconda 创建与删除虚拟环境的完整命令虽然这篇的主线是 venv但实际开发中很多人是 Anaconda 和 venv 混着用的干脆把 conda 的常用操作也列全。创建环境时指定 Python 版本这是 conda 比 venv 强的一点conda create -n data_env python3.10激活conda activate data_env退出conda deactivate查看已有环境conda env list删除环境conda remove -n data_env --all如果想更改默认的虚拟环境安装路径默认在 anaconda3/envs 下面可以修改.condarc文件指定envs_dirs: - D:/envs修改后新建的环境就会安装到D:/envs下。不过实际工作中我还是建议优先试 venv它轻量项目里能直接看见不需要额外管理工具移除了环境不会留下任何残留。5. 常见问题与排查技巧实录5.1 激活不生效 / 提示“不是内部或外部命令”Windows 上报这个错多半是当前路径不对。激活脚本必须在虚拟环境目录下的Scripts或bin目录里执行或者你已经在项目根目录下用相对路径执行。正确操作cd 你的项目目录 .venv\Scripts\activate.bat如果提示“系统找不到指定的路径”先检查.venv目录是否存在目录名是否拼写错误。有些人手滑敲成了.venv结果目录建的是venv这种情况直接把路径换成venv\Scripts\activate.bat就行。在 PowerShell 里遇到“禁止运行脚本”的报错按我前面说的先执行一次Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser这个是 Windows 默认的安全策略挡住了.ps1脚本跟虚拟环境本身没关系放行一次就不会再纠缠。Linux 上如果source .venv/bin/activate提示No such file or directory先确认你创建时用了什么命令如果你敲了python3生成的是.venv/bin如果你用某个 IDE 一键创建的可能目录名不完全一致。用ls -la看一下项目根目录确认实际结构再执行相应路径。5.2 在虚拟环境里执行了 pip install但导入仍然失败这个问题每天都能在技术群里看到。原因十有八九是命令行虽然在虚拟环境里但你运行代码的 IDE 解释器还是全局的。PyCharm 里运行代码用的是右下角配置的那个解释器和你在终端里 activate 哪个环境是两套逻辑。VSCode 同理它运行 Python 文件用的是状态栏选择的解释器不是终端激活的环境。通俗点说你给房间 A 买了新家具但你在房间 B 里找家具当然找不到。解决办法很简单在 PyCharm 里确认右下角或 Settings 里的 Python Interpreter 指向.venv\Scripts\python.exe然后在 IDE 自带的 Terminal 里打开这时 IDE 会自动激活这个环境再执行 pip install。装完之后立刻就能 import 到。在 VSCode 里确认状态栏左下角的解释器是.venv那个然后用 VSCode 自带的终端执行操作扩展会自动完成环境激活两条路径就统一了。另外如果是在命令行手动运行脚本一定要先 activate再执行python main.py。有人直接输入.venv\Scripts\python.exe main.py也能跑这等同于用环境里的解释器但无法自动带上环境变量某些包里依赖的动态库加载会出问题。标准的姿势是 activate 之后再用python命令运行别省那一步。5.3 依赖装错位置的排查与清理有个非常经典的误操作忘了激活环境直接执行pip install把包装到了全局 Python 里。装完发现没问题过了几天换到虚拟环境里运行突然报 ModuleNotFoundError才意识到之前在全局环境里装错了地方。排查时执行pip show 你的包名查看输出的Location字段如果在C:\Users\你的用户名\AppData\Local\Programs\Python\Python311\Lib\site-packages这类路径说明装到全局了。正确应该是在.venv\Lib\site-packages下面。确认装错之后在全局环境里pip uninstall 包名清掉然后在虚拟环境里激活后重新 install 一次。清理依赖时还有一个需求想移除虚拟环境里的某个包但保留其它依赖直接pip uninstall 包名pip 会自动处理这个包对应的依赖关系但如果有别的包依赖它pip 也会一并提示。手动确认是否强制卸载时多看一眼输出就行。5.4 项目目录名带空格引发的路径问题热词里出现了d:\python project\.venv\scripts\python.exe d:\python project\main.py did这样的内容这明显是项目目录名带了中文空格在命令行或 IDE 配置中路径解析出了问题。这种场景下Python 解释器路径的执行在部分终端里会被拆成两段直接导致脚本无法启动。最省心的解决办法是把项目目录从d:\python project\改成d:\python_project\全项目文件统一改名后重新打开。空格在路径中的坑不止 Python很多工具链都会遇到。如果你实在不能用下划线比如项目名必须保持原样那就每次在 IDE 配置时手动用引号把路径包好确保整条路径是一个字符串。PyCharm 和 VSCode 通常会自动处理但命令行手动执行时一定要核对引号是否完整。5.5 venv 创建后无法使用 pip在 Debian/Ubuntu 系 Linux 上这是个新手最容易踩的坑执行python3 -m venv .venv一切正常但激活后执行pip --version提示No module named pip或者直接找不到 pip 命令。原因是系统自带的 python3 环境没有安装 venv 扩展包或 pip 组件venv 模块创建环: 净时没能把 pip 一并装进去。解决办法是sudo apt install python3-venv python3-pip如果已经创建了一个 pip 缺失的环境不用删掉重来激活环境后执行curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py python get-pip.py这个脚本会把 pip 装进当前虚拟环境里然后deactivate再activate一次就能正常使用了。5.6 虚拟环境中的脚本入口python 直接执行 vs 双击运行Windows 上很多人习惯双击文件让它运行但双击运行的 Python 脚本用的是文件关联的默认 Python不是虚拟环境里的 Python。所以你会看到这种情况代码在命令行里跑得好好的一双击就报模块找不到。应对办法是写一个.bat批处理脚本放在项目根目录内容如下echo off call .venv\Scripts\activate.bat python main.py pause这样双击这个.bat会自动激活环境并运行你的主脚本。Linux 上则是写一个.sh脚本内容#!/bin/bash source .venv/bin/activate python main.py然后chmod x run.sh以后直接./run.sh就能跑起来。这个小技巧在给非技术同事交付工具的时候特别好用他们只需要双击一个文件什么环境变量、依赖都不用管。6. 个人经验虚拟环境的几个进阶使用技巧6.1 全局解释器和虚拟环境解释器不要混装我最开始也犯过这个毛病全局 Python 装了 Jupyter、numpy、pandas虚拟环境里又装了一遍结果就是磁盘空间白白浪费而且两台机器上的依赖版本总对不上。后来我给自己定了条规矩除非是环境调试工具否则所有项目依赖一律只装在虚拟环境里全局 Python 只保留最基础的解释器和 pip。这样项目换机器、换同事、上服务器步骤永远是恒定的三连建环境、激活、装依赖。出了问题先看看是不是没有激活环境再看装包的 Location 指向哪里排查路线非常清晰。6.2 善用python -m pip代替直接pip在虚拟环境里pip和python -m pip大多数情况下等价但python -m pip更严谨。原因是pip是入口脚本它的 shebang 可能指向另一个 Python而python -m pip明确告诉系统用当前这个 python 来调用 pip这样装的包一定进当前环境。当你的机器上有多个 Python 版本混装时用python -m pip能避免不少“装到了另一个 Python”的诡异问题。同理运行脚本建议用python main.py而不是直接./main.py尤其是脚本文件没有可执行权限或者 shebang 写得不对的时候。6.3 项目模板化减少重复劳动现在我每开一个新的 Python 项目都会先建好一套标准结构app/源码目录tests/测试目录.venv/虚拟环境不入库requirements.txt依赖清单.gitignore忽略掉.venv、__pycache__、.idea、.vscode等.gitignore里最关键的几行一定要写.venv/ __pycache__/ *.pyc .idea/ .vscode/这样代码提交到仓库时.venv这种动辄上百兆的目录不会进去协作者 clone 下来自己重建环境即可。依赖锁定我用pip freeze生成提交到仓库前再人工过一遍把开发时装的调试工具比如 ipython、jupyter从列表里剔掉让 requirements 尽可能精简。6.4 环境好没有用管理才是关键虚拟环境本质上是个目录你删掉它项目代码一点影响没有。所以别把环境看得多么神圣一般建议在实际使用中一个项目一个环境环境命名清晰依赖版本锁定绝不手动修改环境目录里的任何文件。遇到依赖搅不清的别犹豫直接删了重建。虚拟环境的核心理念就是低成本地试错你越是用得频繁越能感受到它的方便。我后面还打算写一篇把 venv 项目打包部署到服务器时怎么处理系统级依赖的文章到时候可以把这篇文章作为基础篇两篇连着看效果更好。目前这篇里的步骤和排查逻辑覆盖了日常开发九成以上的场景拿着操作基本就能顺畅跑了。
返回列表