Ubuntu下Python虚拟环境创建与实战指南
2026/8/24 19:21:21 网站建设 项目流程

1. 为什么Ubuntu下必须用虚拟环境——不是“多此一举”,而是“生存刚需”

在Ubuntu上写Python项目,最常听到的一句话是:“直接pip install不就行了?”我刚入行时也这么干过。结果是:一个项目跑通了,另一个项目突然报错ImportError: cannot import name 'XXX';删掉重装,发现连pip list都打不开;最后查到是requests版本冲突——A项目要2.25,B项目死活要2.31,而系统级pip只允许存在一个版本。这不是玄学,这是Ubuntu Python生态的真实底色:系统Python是Ubuntu的“命脉”,不是你的“沙盒”

Ubuntu自带的/usr/bin/python3(比如22.04默认是3.10)被apt包管理器深度绑定。你用sudo pip install强行往里面塞包,轻则apt upgrade时报错中断,重则apt autoremove误删关键依赖,导致gnome-shell崩溃、update-manager打不开——我真见过同事因此重装系统三次。这不是危言耸听,而是Ubuntu官方文档明确警告的场景:“Never use sudo pip on Ubuntu”。

所以,“创建虚拟环境”不是Python开发的可选动作,而是Ubuntu环境下Python项目的准入门槛。它本质是创建一个与系统隔离的、可销毁的、带独立pip和site-packages的Python副本。这个副本不碰系统路径,不改/usr,不惊动apt,哪怕你pip install --force-reinstall tensorflow==1.15把整个环境搞崩,只要删掉那个文件夹,Ubuntu就毫发无损。

关键词里反复出现的requirements.txt,就是这个隔离机制的“契约书”。它记录的是“这个项目在此虚拟环境中精确需要哪些包、什么版本”,而不是“我的Ubuntu系统该装什么”。没有虚拟环境,pip install -r requirements.txt就是一场豪赌——赌你系统里没装过冲突的包,赌你没手动升级过某个库的全局版本,赌apt下次更新不会悄悄覆盖你的依赖。而Ubuntu的apt更新频率高、依赖链深,这种赌局十赌九输。

再看热搜词里高频出现的conda创建新虚拟环境显示the channel is not accessible——这恰恰反向印证了问题核心:conda试图在Ubuntu上建立另一套包管理体系,但它的channel源(尤其是默认的anaconda.org)在国内网络环境下极不稳定,错误提示看似是网络问题,实则是conda在Ubuntu上“水土不服”的症状。它想绕过apt,但又没彻底隔离,结果卡在源不可达的死循环里。而原生venv(Python 3.3+内置)不依赖外部源,只调用本地Python解释器,启动快、失败少、路径干净,这才是Ubuntu用户该优先选择的方案。

提示:Ubuntu 20.04及以后版本,python3-venv包默认未安装。很多人执行python3 -m venv myenv报错No module named venv,不是Python坏了,是系统缺这个模块。这是Ubuntu刻意为之的设计——避免用户误用系统Python创建环境,强制你先确认自己真的需要它。

2. 从零开始:Ubuntu下创建虚拟环境的完整链路与每一步的底层逻辑

创建虚拟环境看似一条命令,但背后涉及Ubuntu系统Python结构、权限模型和路径机制。跳过原理直接抄命令,迟早踩坑。下面拆解从系统准备到环境激活的完整链路,每一步都说明“为什么必须这样”。

2.1 系统级准备:确认Python版本与安装venv模块

Ubuntu不同版本预装的Python版本不同:

  • 18.04:Python 3.6(已EOL,不推荐新项目)
  • 20.04:Python 3.8
  • 22.04:Python 3.10
  • 24.04:Python 3.12(LTS尚未发布)

先确认当前系统Python:

python3 --version ls -l /usr/bin/python3*

输出类似:

python3 -> python3.10 python3.10

这表示系统Python是3.10,python3命令指向它。

接着检查venv模块是否存在:

python3 -c "import venv; print(venv.__file__)"

如果报错ModuleNotFoundError: No module named 'venv',说明python3-venv包未安装。这是Ubuntu的默认策略——不自动安装开发相关模块,避免普通用户误操作。安装命令:

sudo apt update sudo apt install python3-venv

注意:这里必须用sudo apt,不能用pip install venv。因为venv是Python标准库的一部分,不是PyPI上的第三方包。pip install venv会安装一个同名但完全无关的废弃包,导致后续python3 -m venv失效。这是新手最常犯的致命错误。

2.2 创建虚拟环境:路径选择、命名规范与隐藏陷阱

假设项目目录为~/myproject,进入该目录:

cd ~/myproject

创建虚拟环境的标准命令:

python3 -m venv venv

这里venv是环境目录名,强烈建议统一命名为venv(小写,无下划线)。原因有三:

  1. VS Code自动识别:VS Code打开项目时,会扫描根目录下的venv.venvenv等名称,自动将其设为Python解释器。用myenvpy310_env,VS Code大概率找不到,需手动配置。
  2. Git忽略惯例.gitignore中通常已有venv/规则,若用其他名字,需额外添加,易遗漏。
  3. 团队协作共识:90%的Python项目都用venv,新人clone代码后source venv/bin/activate即可,无需问“环境目录叫啥”。

但这里有个隐藏陷阱:绝对不要在/tmp/var/tmp下创建虚拟环境。Ubuntu的tmpfiles.d机制会定期清理这些目录下的内容,某天你source venv/bin/activate,发现bin/activate文件没了——不是磁盘坏了,是系统定时清理了。虚拟环境必须放在用户可持久写入的路径,如~/myproject/venv/home/username/projects/myproject/venv

创建完成后,目录结构如下:

venv/ ├── bin/ # 存放python、pip、activate等可执行文件 │ ├── python # 指向venv内部的python解释器(非/usr/bin/python3) │ ├── pip # 指向venv内部的pip │ └── activate # 激活脚本 ├── include/ # C头文件链接(编译扩展时用) ├── lib/ # site-packages所在位置(所有pip安装的包都在这里) │ └── python3.10/ │ └── site-packages/ └── pyvenv.cfg # 配置文件,记录base_python(即系统Python路径)和include_system_site_packages等

关键点:venv/bin/python是一个软链接,指向venv/lib/python3.10/bin/python,而后者是系统Python解释器的硬拷贝(copy-on-write)。这意味着虚拟环境里的Python进程,其sys.path完全独立于系统,/usr/lib/python3.10/site-packages默认不包含在内——这就是隔离的核心。

2.3 激活与验证:如何确认环境真正生效

激活命令:

source venv/bin/activate

成功激活后,终端提示符前会出现(venv)标识:

(venv) user@ubuntu:~/myproject$

此时验证三件事:

  1. Python路径是否切换
    which python # 输出应为:/home/user/myproject/venv/bin/python
  2. pip是否指向虚拟环境
    which pip # 输出应为:/home/user/myproject/venv/bin/pip
  3. site-packages是否为空
    pip list # 输出应只有:pip setuptools wheel(三个基础包) # 绝对不应出现requests、numpy等系统级包

注意:source venv/bin/activate只是临时修改当前shell会话的环境变量(PATHPYTHONHOME等)。关闭终端或新开一个tab,环境自动失效。这是设计使然,不是bug。若需永久激活,应使用echo "source ~/myproject/venv/bin/activate" >> ~/.bashrc,但强烈不推荐——多个项目共用一个激活状态会导致混乱。正确做法是:每次进入项目目录,手动source venv/bin/activate

2.4 升级pip:为什么这步绝不能跳过

新创建的虚拟环境里,pip版本往往很旧(如Ubuntu 22.04的python3.10自带pip 20.3.4)。旧pip存在严重问题:

  • 不支持PEP 517(现代构建标准),安装pydantic等新包会失败;
  • 依赖解析算法有缺陷,pip install -r requirements.txt可能装错版本;
  • 安全漏洞多,2022年后已停止维护。

升级命令:

pip install --upgrade pip

执行后,pip --version应显示≥23.0。这步耗时不到1秒,但能避免后续90%的安装失败。很多教程把它省略,结果读者卡在ERROR: Could not find a version that satisfies the requirement xxx,折腾半天才发现是pip太老。

3. requirements.txt的生成、安装与镜像源实战配置

requirements.txt是虚拟环境的“DNA序列”,它定义了环境的可复现性。但生成和安装过程充满细节,稍有不慎就会导致“在我机器上能跑,在你机器上报错”。

3.1 生成requirements.txt:两种场景的精准策略

场景一:全新项目,从零开始安装依赖这是最干净的方式。在激活的虚拟环境中,逐个安装所需包:

pip install flask requests pandas

然后生成requirements.txt

pip freeze > requirements.txt

pip freeze会导出当前环境中所有已安装包及其精确版本号,格式如:

Flask==2.3.3 Jinja2==3.1.2 Werkzeug==2.3.7 click==8.1.7 itsdangerous==2.1.2 requests==2.31.0 urllib3==1.26.18 ...

优点:绝对精确,环境100%可复现。
缺点:包含大量间接依赖(如Flask依赖的Jinja2Werkzeug),文件冗长,后期维护困难。

场景二:已有项目,需最小化依赖很多项目只需声明“顶层依赖”,让pip自动解决子依赖。这时用pipreqs工具:

pip install pipreqs pipreqs . --encoding=utf8 --force

pipreqs会静态分析项目Python文件(如app.pymain.py),提取import语句,生成仅含顶层包的requirements.txt

flask requests pandas

优点:简洁,便于人工维护,升级时只需改顶层版本。
缺点:无法保证子依赖版本一致,不同pip版本解析结果可能不同。

实战建议:新项目用pip freeze保绝对稳定;成熟项目用pipreqs保可维护性。二者不互斥,可并存:requirements.in(顶层) +requirements.txt(freeze生成的全量)。

3.2 安装requirements.txt:清华镜像源的配置与避坑

国内用户执行pip install -r requirements.txt卡住,99%是pip默认源(pypi.org)访问超时。解决方案不是换conda,而是配置pip镜像源。

方法一:临时指定源(推荐用于单次安装)

pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/

-i参数指定镜像源,清华源(https://pypi.tuna.tsinghua.edu.cn/simple/)稳定、同步及时、无需认证。

方法二:全局配置(一劳永逸)创建pip配置文件:

mkdir -p ~/.pip nano ~/.pip/pip.conf

写入:

[global] index-url = https://pypi.tuna.tsinghua.edu.cn/simple/ trusted-host = pypi.tuna.tsinghua.edu.cn timeout = 120

保存后,所有pip命令自动走清华源。trusted-host是必须项,否则pip因HTTPS证书校验失败而拒绝连接。

踩坑实录:曾有用户配置了清华源,但pip install -r requirements.txt仍超时。排查发现requirements.txt里有一行--find-links file:///path/to/local/wheel,这是本地wheel包路径。pip遇到--find-links会忽略index-url,转而尝试访问本地路径。解决方案:删除该行,或确保本地路径真实存在且可读。

3.3 处理安装失败:常见错误与精准修复

pip install -r requirements.txt失败,不要盲目重试。先看错误类型:

错误1:Could not find a version that satisfies the requirement xxx
原因:requirements.txt中指定了不存在的版本,或包名拼写错误(如pytorch写成torch)。
修复:

  • 检查包名是否正确:pip search xxx(已弃用)或访问 pypi.org 搜索;
  • 检查版本号是否存在:在PyPI页面查看Release history,确认该版本已发布;
  • 临时降级:pip install xxx==2.0.0测试是否版本过高。

错误2:ERROR: Command errored out with exit status 1
原因:包需要编译C扩展(如numpycv2),但Ubuntu缺少编译工具链。
修复:安装构建依赖:

sudo apt install build-essential python3-dev

build-essential包含gcc、make等,python3-dev提供Python.h头文件。没有这两者,pip install numpy必失败。

错误3:ModuleNotFoundError: No module named 'comfyui_manager'
这是热搜词里提到的comfyui生态典型问题。comfyui-manager不是PyPI包,而是GitHub仓库。正确安装方式:

pip install git+https://github.com/ltdrdata/ComfyUI-Manager.git

git+https语法告诉pip从GitHub克隆并安装。同理,openclaw若未上PyPI,也需用此方式。

4. 运行项目:从启动脚本到环境变量的全流程控制

创建好环境、装完依赖,最后一步是运行项目。但这步常被简化为python app.py,实际远比这复杂。

4.1 项目启动的三种模式与适用场景

模式一:直接运行(适合调试)

python app.py

最简单,但隐含风险:若app.py里写了os.environ['DEBUG'] = 'True',这个环境变量只在当前进程有效,重启就丢失。适合快速验证代码逻辑。

模式二:使用环境变量文件(推荐生产)
创建.env文件(与requirements.txt同级):

FLASK_ENV=development FLASK_DEBUG=True DATABASE_URL=sqlite:///./app.db SECRET_KEY=my-secret-key

安装python-dotenv

pip install python-dotenv

app.py开头添加:

from dotenv import load_dotenv load_dotenv() # 自动加载.env文件

启动时无需额外参数,环境变量自动注入。.env文件应加入.gitignore,避免密钥泄露。

模式三:systemd服务(Ubuntu服务器长期运行)
若项目需开机自启、后台运行、自动重启,必须用systemd。创建服务文件:

sudo nano /etc/systemd/system/myproject.service

内容:

[Unit] Description=My Python Project After=network.target [Service] Type=simple User=user WorkingDirectory=/home/user/myproject Environment="PATH=/home/user/myproject/venv/bin" ExecStart=/home/user/myproject/venv/bin/python /home/user/myproject/app.py Restart=always RestartSec=10 [Install] WantedBy=multi-user.target

启用服务:

sudo systemctl daemon-reload sudo systemctl enable myproject.service sudo systemctl start myproject.service

Environment="PATH=..."确保systemd使用虚拟环境的Python,而非系统Python。Restart=always保证进程崩溃后自动拉起。

4.2 调试与日志:让问题浮出水面

Ubuntu下Python项目静默失败很常见。必须主动捕获日志:

基础日志配置(在app.py中):

import logging logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler('/home/user/myproject/app.log'), logging.StreamHandler() # 同时输出到终端 ] ) logger = logging.getLogger(__name__) logger.info("Application started")

查看实时日志

tail -f /home/user/myproject/app.log

若用systemd服务,查看日志更简单

sudo journalctl -u myproject.service -f

journalctl会聚合所有输出,包括stderr,比直接看log文件更可靠。

4.3 环境迁移:当需要把项目搬到另一台Ubuntu机器

虚拟环境本身不可迁移(路径硬编码),但requirements.txt可完美复现。迁移步骤:

  1. 在原机器生成requirements.txt(确保用pip freeze);
  2. 将项目代码、requirements.txt.env(如有)打包:
    tar -czf myproject.tar.gz myproject/
  3. 在新Ubuntu机器解压,创建新虚拟环境:
    cd myproject python3 -m venv venv source venv/bin/activate pip install --upgrade pip pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/
  4. 验证:
    python -c "import flask, requests; print('OK')"

关键经验:不要尝试cp -r old_venv new_venv。虚拟环境里有绝对路径(如pyvenv.cfg中的home = /usr/bin/python3),复制后python命令会指向原机器路径,必然失败。唯一可靠的迁移方式,就是“重建环境+重装依赖”。

5. 高级技巧与避坑清单:Ubuntu Python开发者的实战笔记

以上是标准流程,但真实开发中总有些“意料之外”。以下是我在Ubuntu上踩过的坑,总结成可立即落地的技巧。

5.1 解决“无法创建虚拟环境:早期版本”错误

错误信息:The virtual environment was not created successfully because ensurepip is not availableUnable to create virtual environment for python 2.7
根本原因:Ubuntu系统Python被降级或损坏。例如,用户手动sudo apt install python3.8后,python3软链接未更新,python3 -m venv仍调用旧版。

诊断:

ls -l /usr/bin/python3 python3 --version python3.10 --version # 显式调用具体版本

修复:

sudo update-alternatives --config python3 # 选择正确的python3.10条目 sudo rm /usr/bin/python3 sudo ln -s /usr/bin/python3.10 /usr/bin/python3

5.2 WSL2安装Ubuntu卡在0%的终极解法

热搜词里高频出现wsl2安装ubuntu一直卡在安装0%。这不是网络问题,而是WSL2的vmcompute服务未启动。

Windows PowerShell(管理员)执行:

# 启用Hyper-V(WSL2必需) dism.exe /online /enable-feature /featurename:Microsoft-Hyper-V /all /norestart # 启用WSL dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart # 重启后,设置WSL2为默认 wsl --set-default-version 2 # 若仍卡住,重置网络 netsh winsock reset netsh int ip reset

5.3 VS Code配置Python解释器的三步确认法

VS Code常“找不到”虚拟环境。按此顺序排查:

  1. 打开命令面板(Ctrl+Shift+P),输入Python: Select Interpreter
  2. 在列表中选择./venv/bin/python(路径必须精确到bin/python,不能只选venv文件夹);
  3. 查看右下角状态栏,确认显示Python 3.10.12 64-bit ('venv': venv),且括号内有venv标识。

若列表为空,执行:

code --install-extension ms-python.python

重启VS Code。

5.4 清理磁盘空间:Ubuntu下Python环境的瘦身指南

热搜词提到“占用磁盘内存已经90个g了”。Python环境臃肿主因是~/.cache/pipvenv残留。

清理缓存:

pip cache info # 查看缓存位置 pip cache purge # 彻底清空

清理无效虚拟环境:

# 查找所有名为venv的目录 find ~ -type d -name "venv" -path "*/venv" | grep -v ".local/share/virtualenvs" # 手动删除确认不再需要的venv目录 rm -rf ~/old_project/venv

5.5 替代方案对比:venv vs conda vs pipx

方案适用场景Ubuntu兼容性学习成本典型错误
venv(推荐)标准Python项目,依赖纯PyPI包★★★★★(原生支持)忘记sudo apt install python3-venv
conda科学计算、需混合C/C++/Fortran包(如numpyscipy★★☆☆☆(channel不稳定)conda create -n env_name python=3.10后,conda activate env_name失败(未初始化shell)
pipx全局安装CLI工具(如blackpoetry),避免污染~/.local/bin★★★★☆(需pip install pipxpipx install xxx后,命令不在PATH(需export PATH="$HOME/.local/bin:$PATH"

结论:Ubuntu用户,95%的场景用venv足矣。conda是为跨平台科学计算设计的,不是为Ubuntu优化的。强行用conda,只会把简单问题复杂化。

最后分享一个小技巧:在项目根目录创建run.sh脚本,内容如下:

#!/bin/bash # 检查venv是否存在 if [ ! -d "venv" ]; then echo "Creating virtual environment..." python3 -m venv venv source venv/bin/activate pip install --upgrade pip pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple/ else echo "Activating existing virtual environment..." source venv/bin/activate fi # 启动项目 python app.py

赋予执行权限:chmod +x run.sh,以后只需./run.sh,一键完成环境检查、依赖安装、项目启动。这是我每个新项目必加的“懒人脚本”,省去重复劳动,也杜绝了忘记升级pip的失误。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询