十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

Python虚拟环境venv实战:创建、激活、迁移与避坑

Python虚拟环境venv实战:创建、激活、迁移与避坑 1. 为什么每个Python项目都需要一个独立的环境1.1 依赖冲突——所有Python开发者都遇到过的噩梦先说个我真实的经历。几年前我在给一个老项目做维护它用的是Django 3.2装在我当时那台电脑的全局Python环境里。后来接了个新活要新建一个Django项目我图省事直接全局升级了Django到4.2。升级很顺利新项目开发也很顺手结果凌晨收到老项目报警——页面直接500。一看日志Django 4.2去掉了几个旧API老项目里的第三方插件全炸了。那一晚我一边回滚一边在心里骂自己为什么不早一点用虚拟环境。这就是Python虚拟环境venv要解决的核心问题。每一个Python项目都会依赖一堆第三方库而这些库有各自的版本要求。如果没有隔离机制所有项目共享同一个site-packages目录你想给A项目升级某个库B项目可能就直接跑不起来了。虚拟环境做的事情很简单也很有用给每个项目单独开辟一个属于它自己的Python运行空间里面装着这个项目专属的Python解释器、pip和所有第三方包互相之间完全隔离。新手可能觉得我刚开始学Python就写点小脚本需要这么麻烦吗说句实在话哪怕只写过三五个独立的小脚本只要有一天你开始装爬虫库、数据处理库、GUI库就一定会遇到版本冲突。早一天养成用venv的习惯就晚一天被依赖地狱折磨。本文适合所有Python开发者阅读从刚入门的小白到需要维护多个项目的资深工程师venv都是基本功。1.2 venv和conda、pipenv、poetry之间怎么选很多初学者一查资料发现除了venv还有一大堆环境管理工具直接晕了。我来帮你理清楚。venv是Python官方自带的模块从Python 3.3开始就内置了3.5之后成为推荐方案。它的特点是轻量、零额外依赖、开箱即用。你不需要安装任何东西只要有Python就能创建虚拟环境。它的局限性也很明显只能创建虚拟环境不能帮你管理Python本身的版本。conda包括Anaconda和Miniforge是一个发行版级别的环境管理器它比venv重得多但能做的事情也多得多。conda不仅能管理Python包还能管理Python解释器版本甚至能管理很多非Python的原生库比如CUDA、cuDNN、OpenCV这些在数据科学和机器学习领域非常流行。热词里提到的“miniforge创建虚拟环境”“conda创建虚拟环境”“anaconda中创建虚拟环境时如何更改环境”都是这个范畴。但conda也有代价安装它本身就占好几个GB的空间而且它默认的依赖解析速度偏慢。pipenv和poetry走得是另一条路它们不仅管虚拟环境还管依赖声明和锁文件偏向工程化。poetry有强大的版本解析能力pyproject.toml一步到位适合有严格依赖管理需求的团队项目。pipenv则是用Pipfile和Pipfile.lock来管理依赖。我的建议很简单如果你只是写Python脚本、做爬虫、做Web开发或者搞自动化测试直接用venv就够了。如果你主要做数据分析、机器学习需要频繁切换Python版本或装CUDA这类原生库那用conda更省心。如果你在团队里维护一个规范化的项目希望依赖声明和构建发布一体化poetry可以试试。工具没有绝对的好坏关键看你的应用场景。2. venv的完整使用流程2.1 三步创建虚拟环境Windows/Linux/macOS通用创建虚拟环境的命令一条就够python -m venv .venv这条命令会在当前目录下创建一个名为.venv的文件夹。Windows下会生成.venv\Scripts\python.exe和.venv\Scripts\pip.exeLinux和macOS下会生成.venv/bin/python和.venv/bin/pip。为什么用.venv这个名字因为它以点开头是隐藏目录而且很多工具比如VSCode、PyCharm、Git都默认把.venv加入忽略列表用起来省心。创建时有两个比较常用的参数我建议了解一下。第一个是--system-site-packagespython -m venv --system-site-packages .venv加上这个参数后虚拟环境会继承全局环境里已经安装的包创建速度快很多也能复用系统里已经装好的大体积库比如numpy、torch这类。但副作用是这些包不会被隔离和“完全隔离”的初衷有出入。我一般只在极少数需要访问系统级Python扩展的场景才会用这个参数普通项目不加。第二个是--promptpython -m venv --prompt my-project .venv默认情况下激活虚拟环境后终端提示符前面会显示(.venv)用过--prompt后可以自定义成你想要的名字。比如同时维护多个项目时可以给每个环境起一个容易区分的提示符避免开一堆终端后分不清当前在哪个环境里。2.2 激活、退出与日常使用创建完成后使用虚拟环境的关键一步是激活。不同操作系统、不同Shell的激活命令不一样这是新手最容易搞混的地方。Windows的Command Promptcmd.venv\Scripts\activate.bat通常直接敲.venv\Scripts\activate也行因为Windows会补全后续。Windows的PowerShell.venv\Scripts\Activate.ps1PowerShell默认会禁止执行脚本你需要先修改执行策略Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser注意执行策略只对当前用户生效不要加-Scope LocalMachine免得影响系统设置。Linux和macOS的Bash/Zshsource .venv/bin/activate激活成功后终端提示符前面会出现类似(.venv) PS C:\Users\Administrator\pycharmprojects\pythonproject这样的前缀。热词里提到的(.venv) ps c:\users\administrator\pycharmprojects\pythonproject说明环境已经激活了。这个时候你执行pip install包就会装进这个虚拟环境里不会污染全局。激活之后就是正常的日常开发流程pip install requests pip list python app.py需要退出环境时不用特别记命令执行deactivate如果想不激活直接使用环境也可以。用绝对路径指定解释器# Windows PowerShell .venv\Scripts\python.exe app.py # Linux/macOS .venv/bin/python app.py这种不激活直接调用的方式在crontab定时任务、supervisor进程守护、systemd服务这些场景下非常实用因为不需要依赖某个Shell的激活状态。2.3 在PyCharm和VSCode中正确配置venv热词里有一条很典型的报错cannot run program c:\users\顾征宇\desktop\pythonproject\.venv\scripts\pyth...这是PyCharm或系统里配置的解释器路径出了问题。最常见的原因是创建venv时没激活或者路径不对实际文件并不是这个位置。在PyCharm中配置venv的步骤打开File文件菜单进入Settings设置找到Project Python Interpreter点击右侧的设置图标选择Add Interpreter再选Existing Environment浏览到.venv\Scripts\python.exeWindows或.venv/bin/pythonLinux/macOS。一定要精确选到python.exe这个文件本身而不是选到.venv目录。热词里还有“pycharm2025中选择不到已经创建的虚拟环境”的问题。这通常是PyCharm的缓存索引没刷新。解决方法是先点击设置界面里的Show All把添加过的解释器列表打开手动移除旧的再重新添加。如果还是选不到直接关掉PyCharm删除项目目录下的.idea文件夹然后重新打开项目让PyCharm重新扫描。VSCode的配置思路类似。安装好Python扩展后按下CtrlShiftP打开命令面板输入并选择Python: Select Interpreter然后在列表中找到.venv对应的解释器。如果列表里没有点击Enter interpreter path手动指定。VSCode还有一个贴心的小细节当你打开一个包含.venv的目录时右下角会弹出提示询问是否切换到这个虚拟环境直接点“是”就行。VSCode里指定解释器还有一个坑即使你选了.venv的解释器终端里跑python命令时用的也可能是全局Python。原因是VSCode的终端初始化时没有自动激活虚拟环境。解决方法是让VSCode在打开终端时自动激活。你可以这样设置按下CtrlShiftP打开Preferences: Open Settings (JSON)在settings.json里加上{ python.terminal.activateEnvironment: true, python.terminal.activateEnvInCurrentTerminal: true }这样每次打开新的集成终端VSCode会自动激活项目里的venv省去手动激活的麻烦。3. 依赖管理的核心技巧3.1 用requirements.txt精确锁定项目依赖虚拟环境创建好之后下一步就是把项目依赖固化下来让别人或者未来的自己能快速复现环境。最基础的工具就是requirements.txt。在虚拟环境激活状态下执行pip freeze requirements.txt这样会把当前虚拟环境里所有已安装的包和精确版本号写进文件格式大概是这样的Django4.2.5 requests2.31.0 urllib32.0.4换一台机器或者另一个环境只需要pip install -r requirements.txt就能批量安装所有依赖。这里面有个细节值得一提。pip freeze和pip list看起来差不多但pip freeze只输出包名和版本的静态快照适合生成requirements文件pip list则带格式化表格输出同时列出pip、setuptools这类管理工具本身适合人工查看。生成requirements时一定要用pip freeze而不是pip list。pip freeze有一个不太想做又不得不提的问题它会把虚拟环境里所有的包都导出来包括一些间接依赖。如果你只想记录项目直接引用的顶层依赖可以用pipreqs这个工具pip install pipreqs pipreqs . --forcepipreqs会扫描项目代码里的import语句自动推断出实际用到的包生成一个干净精简的requirements.txt。我个人的习惯是给开源项目或有严格规范要求的项目用pipreqs保证requirements清单干净给自己维护的私有项目用pip freeze因为私有项目不介意冗余更在意能精确复现。3.2 虚拟环境的备份、复制与迁移热词里有“python虚拟环境迁移”这个问题问的人特别多。有个必须强调的结论不要直接复制整个.venv目录到另一台电脑上。原因有两个第一venv里面存储了绝对路径比如Windows下pyvenv.cfg文件里会记录创建时用的Python路径新机器上路径不一致环境就无法正常使用第二venv依赖的是创建时对应的Python解释器换机器后如果Python版本不同虚拟环境里的包可能完全不兼容。正确的迁移流程是在旧环境里生成requirements.txt然后在目标机器上创建全新的venv并重新安装依赖。具体做三步# 旧机器上导出依赖 pip freeze requirements.txt # 新机器上创建并激活虚拟环境 python -m venv .venv source .venv/bin/activate # Windows用 .venv\Scripts\activate # 安装依赖 pip install -r requirements.txt如果你的项目比较大依赖包很多建议顺手导出两份清单一份是精确版本的requirements.txt一份是和Python版本绑定的说明比如在项目README里注明“本工具兼容Python 3.10及以上”。这样迁移时即使找不到一模一样的包版本也能快速定位是不是Python版本不匹配导致的问题。还有一个更省事的方案如果你和团队都用Docker可以把虚拟环境直接放进Docker镜像里。在Dockerfile中创建并激活venv然后把整个venv目录的路径固定下来这样可以完全绕开宿主机Python环境差异的问题。4. 常见问题排查与避坑指南4.1 创建venv失败python -m venv不成功的典型原因热词里有“python3.10.11 -m venv不成功”这个现象我帮别人排查过很多次主要原因集中在三种。第一种是环境变量没配好。系统里装了多个版本的Python或者某个第三方工具自带了一个Python导致你在终端里敲python时实际执行的不是你期望的那个解释器。排查方法是先执行where python # Windows which python # Linux/macOS看返回的路径是什么。如果你期望的是Python 3.10.11但返回的是某个工程软件自带的Python那就说明PATH的优先级不对。解决方法是调整环境变量的顺序或者直接用完整路径调用Python比如C:\Python310\python.exe -m venv .venv。第二种是ensurepip模块缺失。创建venv的时候python默认会调用ensurepip来安装pip。如果Python安装时没有包含这个模块或者在某些精简版Python比如有些发行版的软件源里默认不装pip中就会出现报错Error: Command [...\\venv\\Scripts\\python.exe, -Im, ensurepip, --upgrade, --default-pip] returned non-zero exit status.解决方法是先创建一个不带pip的虚拟环境再手动安装pippython -m venv --without-pip .venv source .venv/bin/activate curl -O https://bootstrap.pypa.io/get-pip.py python get-pip.pyWindows下也可以用同样的思路先下载get-pip.py再放到.venv目录下执行。第三种是在错误的工作目录下创建了Ven环境。比如你刚好在一个Python安装目录、一个已经存在的venv目录或者带中文路径的目录下执行命令可能引发一些奇怪的权限或路径问题。我踩过的坑里最无语的一次是用户在C:\Program Files\Python310\Scripts\里执行创建因为那个目录需要管理员权限创建出的虚拟环境刚建好就没法写入文件。遇到这种问题先切换到独立的项目目录再执行创建。4.2 激活失败和pip指向错误的速查思路激活失败是另一个高频问题表现形式五花八门但原因通常就几种。PowerShell报错最典型错误信息大概是这样无法加载文件 .venv\Scripts\Activate.ps1因为在此系统上禁止运行脚本。这就是前面说过的PowerShell执行策略问题。执行Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser然后按提示输入Y即可。这个方法只对当前用户生效比较安全不需要管理员权限。激活后依然发现pip install装到了全局环境这种情况我见过不少次。建议按下面这个顺序排查确认激活成功。看终端提示符前面有没有(.venv)前缀最好再执行where python看路径是否指向.venv\Scripts\python.exe。确认是否是在激活状态下打开的新终端。如果你在激活前就开了一个终端激活命令是在另一个终端里执行的两者状态不会同步。解决办法很简单关闭所有终端重新打开一个再执行激活。确认当前Shell没有自定义的别名或脚本干扰。比如有些用户的.bashrc里写死了alias pip/usr/bin/pip3或alias python/usr/bin/python3这类别名会绕过虚拟环境。检查一下alias输出把冲突项去掉。还有一个容易混淆的点在激活状态下执行pip list和python -m pip list结果应该是一致的因为虚拟环境里的pip和python是绑定的。但如果你在激活状态下先执行了cd /tmp或者切到了其他目录而那个目录下碰巧有一个python启动器配置就有可能出现解释器混乱。这类问题不好查我一般建议用一条命令快速定位当前Python的实际路径python -c import sys; print(sys.executable)如果输出的路径指向.venv说明环境激活正常。如果还指向全局Python那说明激活有问题就不用再猜了。4.3 虚拟环境的清理与删除Django等项目适用热词里有“django虚拟环境怎么删除”这个操作比很多人想象中简单。venv的整个生命周期里所有内容都存在于.venv目录中删除环境就是删掉这个目录。Linux/macOS下执行rm -rf .venvWindows下直接打开资源管理器删除项目文件夹里的.venv目录即可。如果你在PyCharm里需要先到File Settings Project Python Interpreter里把该解释器移除再删除.venv目录否则PyCharm可能会提示这个解释器路径不存在。删除虚拟环境不影响你的项目代码所有源码、静态文件、数据库文件都不会受影响。Django项目尤其如此manage.py、settings.py、各应用的代码都在项目外层与.venv完全无关。删掉虚拟环境后只需要重新创建、重新pip install -r requirements.txt项目就能恢复运行。有一点需要提醒你删除虚拟环境之前先确认虚拟环境里有没有未导出到requirements文件的包。如果你只是临时用了一个包没写进requirements删掉环境后还得重新查版本号。稳妥的做法是先执行一遍pip freeze requirements.txt再删。我有次就是删环境前忘了导出结果一个老项目里某个小众库的精确版本号找不回来了后来到脚本源码里根据import一个一个排查白白浪费了一个下午。4.4 在venv里安装PyTorch、CUDA和cuDNN的注意事项热词里提到“虚拟环境安装pytorch”“虚拟环境安装cuda和cudnn”这些其实都是数据科学场景里的常见操作。先说结论venv可以隔离Python包但管不了系统级的CUDA驱动和cuDNN库。CUDA驱动是装在操作系统层面的venv隔离不了也不需要隔离。venv能做的事是把PyTorch对应的Python版本装到虚拟环境里同时通过wheel方式绑带对应的CUDA运行时库。安装GPU版本的PyTorch标准做法是到PyTorch官网pytorch.org选择自己的操作系统、包管理工具、CUDA版本然后复制它生成的命令。举个例子如果你的CUDA版本是12.1选择pip安装命令通常是pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121请注意这里用的是--index-url参数它会从PyTorch官方仓库下载而不是从PyPI安装。因为PyPI上的torch默认是CPU版本直接pip install torch装出来的包没有GPU支持很多人装了之后一跑代码显示torch.cuda.is_available()是False就是栽在这个坑上。至于CUDA和cuDNN如果你用pip方式安装PyTorch它会自带一个配套的CUDA运行时库一般不需要单独在venv里再装一遍。但如果你需要跑一些依赖外部CUDA工具链的项目比如安装某些需要编译的扩展包那就得确保系统里装了合适的CUDA Toolkit并把nvcc加到PATH里。这种情况与venv无关属于系统环境层的配置。再补充一个常见的排查问题在venv里装了torch运行项目时提示“ImportError: libcudart.so.xxx: cannot open shared object file”。这说明它找到了Python包但找不到对应的CUDA动态库。可以检查一下当前环境的LD_LIBRARY_PATH是否包含了CUDA的lib目录或者考虑重新安装一个与系统CUDA版本匹配的PyTorch wheel版本。4.5 打包成exe、PyQt6虚拟环境未激活等琐碎问题热词里还有几条很典型的问题我放在一起说说。“pyqt6.qtcore 虚拟环境未激活”这条本质是Python解释器选错了。很多人用PyQt6写GUI装包的时候没注意环境直接全局装了然后在VSCode或PyCharm里运行时项目又选了别的解释器于是报错说找不到PyQt6模块。解决办法就是先把虚拟环境激活确认pip list里有PyQt6再确认当前IDE选中的解释器是同一个。如果确认无误还报错执行python -c import PyQt6.QtCore; print(PyQt6.QtCore.QT_VERSION)根据返回结果判断PyQt6是不是真装上了。“python创建表格怎么只能65536”这个问题的根源是用了xlwt库。xlwt是写Excel 2003格式xls的库而xls格式规定的最大行数就是65536行。想突破这个限制改用openpyxl或xlsxwriter写xlsx格式就行。顺带说一句这个问题的解决方法和venv没有直接关系但如果你用的是Python扩展安装的lib可能需要在新的venv里重新pip install openpyxl旧环境里的依赖迁移不过来。“python打包成exe”是另一个高频需求。在虚拟环境里用PyInstaller打包效果远好于全局环境打包。原因是虚拟环境里只装了这个项目用到的依赖打包出来的exe体积更小、更干净。操作就是先激活venv然后pip install pyinstaller pyinstaller -F app.py注意PyInstaller本身也要装进venv里别图省事在全局环境直接调pyinstaller命令否则打包时它可能会追溯到全局的Python包里去导致打出来的exe带上一堆无关依赖。5. 进阶venv在真实项目中的工程化实践5.1 一个项目多个venv开发、测试、生产环境隔离很多人觉得venv很基础动动嘴就会但实际上把它工程化用好的团队不多。一个看起来“装13”但实际很管用的做法是在同一个项目里维护多个虚拟环境。比如.venv-dev开发环境装项目的基础依赖外加ipython、pytest、pre-commit这些开发工具。.venv-test测试环境专门跑自动化测试依赖文件用requirements-test.txt管理。.venv-prod生产环境只装项目真正运行所需的依赖用requirements-prod.txt管理。当然实际项目里不常用的环境不用每个都建好但“开发依赖”和“生产依赖”分开的理念建议尽早培养。比如Django项目生产环境需要gunicorn开发环境需要pytest-django和django-debug-toolbar如果都放进同一个requirements文件生产环境会多出一堆没用的开发库既浪费内存又增加安全风险。具体的拆分方式很简单。项目根目录下维护两个文件# requirements.txt生产依赖 Django4.2.5 gunicorn21.2.0 requests2.31.0 # requirements-dev.txt开发依赖包含生产依赖 -r requirements.txt pytest7.4.2 pytest-django4.5.2 django-debug-toolbar4.2.0安装时pip install -r requirements.txt # 开发环境 pip install -r requirements-dev.txt这样做的最大好处是环境边界清晰。生产环境出问题能快速排除“是不是装了某个开发库导致依赖冲突”的干扰。我自己接手的几个项目都是因为一开始没拆后来出了问题只能一个一个手动排查非常痛苦。5.2 用好.gitignore别把.venv提交到仓库虚拟环境目录命名成.venv的一大好处就是大多数工具默认会忽略它。但在你自己的项目里还是建议显式在.gitignore里加上.venv/ venv/ __pycache__/ *.pyc为什么不提交.venv除了它体积大、不便于diff之外更重要的是它记录了创建时的绝对路径和特定平台的依赖提交到仓库后对别人基本没有意义。别人拉下来的代码只需要一份requirements.txt就能自己重建环境。5.3 venv与后台任务、部署脚本的配合最后说一个venv在日常运维里的实用技巧。很多人在服务器上部署Python服务时习惯先source activate再启动服务。从功能上讲没问题但如果你用的是systemd、supervisor这类进程守护工具配置起来比较麻烦因为每个进程都要手动指定激活脚本。其实可以绕开激活直接用venv里Python解释器的绝对路径启动/home/deploy/project/.venv/bin/python /home/deploy/project/manage.py runserver 0.0.0.0:8000在systemd的Unit文件里写[Service] ExecStart/home/deploy/project/.venv/bin/gunicorn config.wsgi:application -w 4 -b 0.0.0.0:8000 WorkingDirectory/home/deploy/project这样既不依赖Shell的激活状态也不需要额外写一段source激活逻辑简单直接。venv的核心价值在于隔离但隔离之后怎么把环境用起来才能真正体现它的工程意义。写在最后的小建议如果让我给初学Python的朋友一句过来人的建议我会说创建一个新项目的时候第一件事就是建虚拟环境。不用想不用犹豫不管项目多小都先python -m venv .venv然后激活再开始装包。这个习惯练成了几年下来能替你省下无数个“为什么这个项目突然跑不起来了”的深夜。venv这个东西门槛极低但价值极高。它能帮你规避依赖冲突能让项目的复现变得干净利落也能让你和团队协作时少很多“在我机器上明明正常”的尴尬。希望这篇指南能帮你在虚拟环境的路上少踩几个坑。
返回列表