Anaconda 安装和虚拟环境配置这两件事,几乎所有 Python 开发者都绕不过去,但真正能把它们讲透的人并不多。我见过太多人卡在"装完了但 conda 命令不认""换了个项目就报包版本冲突""在 VS Code 里选错解释器跑到崩溃"这些环节上,最后干脆把所有包都往 base 环境里堆,环境越用越脏,重装系统成了唯一出路。这篇内容就是把我这些年踩过的坑、验证过的方案完整摊开:从选 Anaconda 还是 Miniconda、三个平台的安装细节,到虚拟环境的创建、导入导出、多环境与 VS Code、Jupyter 的联动配置,再到高频报错的排查路径。不管你是刚上手的新人,还是已经有一堆环境但理不清关系的老手,都能在这里找到可以直接抄的操作步骤和参数选择逻辑。
1. 先想清楚:Anaconda 到底该不该装,装哪个版本
1.1 一个真实场景:裸装 Python 为什么会让人崩溃
刚学 Python 的时候,大家的路径通常是去官网下个安装包,一路 Next,然后在全局环境里pip install各种库。前两个月没问题,等你同时在做两个项目——一个要用 PyTorch 1.x 配 CUDA 11,另一个要用新版 PyTorch 配 CUDA 12——麻烦就来了。同一个全局环境里,两套依赖互相打架,装了新的旧项目跑不动,回退旧的新的又报错。更崩溃的是系统自带的 Python 被某些底层工具链依赖,你动它一下,系统里的其他软件可能跟着出问题。
虚拟环境解决的就是这个问题:给每个项目一个独立的、互不干扰的包目录。你可以把它想象成给每个项目配一个独立的工具箱,扳手、螺丝刀各放各的,谁也不要去动别人的抽屉。而 Anaconda 做的事情更往前一步,它不只是管 Python 包,还管 Python 解释器本身、管编译好的二进制依赖(比如 BLAS、MKL、FFT 这些科学计算底层库)、管非 Python 的包(比如 R、编译器工具链)。所以做数据科学、机器学习、生信分析这类领域的同学,用 Anaconda 的收益最明显。
顺便提一句,很多人搜索的时候会把 Anaconda 拼成 "Anconda",缩写也常写成 "anconda"。官方正确的拼法是 Anaconda,搜索资料、找文档的时候注意一下,拼错了很容易搜到不相关的东西。
1.2 Anaconda、Miniconda、venv 三者的分工与选型
这三者不是替代关系,而是适用场景不同。我把它们的关键差异整理成了一张表,你可以直接对着自己的需求选:
| 方案 | 体积(安装后) | 自带包数量 | 是否管解释器 | 跨语言支持 | 适合谁 |
|---|---|---|---|---|---|
| Anaconda Distribution | 约 4-6 GB | 1500+ 预装包 | 是 | 是 | 新手、数据科学、教学环境 |
| Miniconda | 约 400 MB | 只含 conda 和 Python | 是 | 是 | 老手、CI/CD、服务器、容器 |
| venv / virtualenv | 几乎为 0(复用系统 Python) | 无 | 否 | 否 | 纯 Web 开发、追求轻量 |
| pip + venv 组合 | 同上 | 无 | 否 | 否 | 部署环境、镜像构建 |
我自己的选择逻辑是这样的:本地主力开发机装 Miniconda,因为 Anaconda 预装的那 1500 个包我大概只会用到三四十个,剩下的全是磁盘负担,而且预装包版本一旦和你项目需求冲突,反而要额外处理。给完全零基础的朋友装机,我会推荐 Anaconda 图形安装包,因为省心,装完jupyter notebook直接能用,不用折腾前端资源。而线上服务器、Docker 镜像里,一律 Miniconda,镜像体积能小好几个 G,构建速度差别非常明显。
至于 venv,它和 conda 环境不冲突。纯后端项目、依赖全在 PyPI 上、不需要 CUDA 这类复杂二进制依赖的情况下,venv 完全够用,而且启动更快、磁盘占用更小。不要因为学了 conda 就什么项目都上 conda,那是另一种形式的过度设计。
1.3 安装前的三件事:磁盘、杀软、路径
这三件事不提前处理,装到一半出问题的情况特别多,我按重要性排一下。
第一是安装路径。千万不要用带中文、空格的路径,比如C:\Users\张三\我的软件\。conda 内部有大量脚本会拼接路径字符串,中文和空格在部分包(尤其是需要编译的包)的构建脚本里会直接报错,而且报错信息往往指向别的地方,极难排查。我建议 Windows 上直接装在D:\anaconda3或C:\anaconda3这类纯英文短路径下,Linux 和 macOS 装在$HOME/anaconda3或$HOME/miniconda3。
第二是磁盘空间和文件系统。conda 创建环境时默认使用硬链接(hardlink)复用已经下载过的包文件,也就是说同一个包在多个环境里只占一份磁盘。但硬链接有个硬性前提:环境目录和包缓存目录必须在同一个文件系统(同一个盘符)上。如果你把pkgs_dirs放在 C 盘、把envs_dirs放到 D 盘,硬链接失效,每个环境都会真真切切地复制一份依赖,一个 PyTorch 环境就能吃掉 5-8 GB。所以要么统一放一个盘,要么显式配置好缓存和环境的路径。
第三是安全软件的实时扫描。conda 解包时会一次性写入成千上万个小文件(Python 包里全是 .py 和 .pyc),实时扫描会把解包速度拖慢好几倍,我实测过某安全软件开着的时候装 PyTorch 要十几分钟,加白名单后三分钟出头。所以装之前把安装目录和pkgs缓存目录加进排除列表,装完再决定要不要解除。
2. Anaconda 安装实操:三个平台逐条走一遍
2.1 Windows:图形安装程序与静默安装
Windows 是最容易出问题的平台,因为涉及 PATH 环境变量的处理。官方安装包里有一个很关键的勾选项:Add Anaconda3 to my PATH environment variable。官方的建议是不勾,理由是会干扰系统里其他程序。我同意这个建议,但要注意它的副作用:不勾的话,你只能在"Anaconda Prompt"里用 conda,普通 CMD 和 PowerShell 里conda命令是不存在的。
如果你希望在任何终端里都能用,正确做法不是勾那个选项,而是装完之后手动执行初始化:
# 在 Anaconda Prompt 里执行,为 PowerShell 初始化 conda init powershell # 为 CMD 初始化 conda init cmd.exe执行完关闭终端重新打开,conda activate就能用了。这里有个高频报错:PowerShell 提示"因为在此系统上禁止运行脚本,无法加载文件 profile.ps1"。这是 PowerShell 的执行策略限制,用下面这条命令放开当前用户级别即可:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser如果你要做批量部署或者写自动化脚本,图形安装器其实支持静默安装:
# /S 静默,/D 指定目录(必须是最后一个参数,且不能加引号) Start-Process -Wait -FilePath ".\Anaconda3-2024.10-1-Windows-x86_64.exe" ` -ArgumentList "/S", "/D=D:\anaconda3"注意/D参数后面不能有引号,路径里也不能有空格,这是 NSIS 安装器的老规矩,踩过一次就记住了。
2.2 macOS 与 Linux:命令行安装更省事
macOS 上我从来不用图形安装包,直接下命令行版 pkg 或者 shell 脚本。用 shell 脚本自由度更高,可以自定义路径:
# 下载(Intel 芯片用 x86_64 版本,M 系列芯片用 arm64 版本) curl -O https://repo.anaconda.com/archive/Anaconda3-2024.10-1-MacOSX-arm64.sh # 安装到指定目录,-b 表示批处理模式(自动同意协议) bash Anaconda3-2024.10-1-MacOSX-arm64.sh -b -p $HOME/anaconda3 # 初始化 shell(zsh 是 macOS 默认) $HOME/anaconda3/bin/conda init zshLinux 服务器上的流程几乎一样,只是要注意:如果是 root 用户装机、多用户共用,建议装到/opt/anaconda3然后给每个用户配置各自的envs_dirs,否则大家的环境混在一个目录下,权限和命名都会乱。还有一点,服务器上通常没有图形界面,-b参数是必须的,否则脚本会卡在交互式协议确认那里,在 CI/CD 流水线里表现为超时失败。
# Linux 服务器推荐写法 wget https://repo.anaconda.com/archive/Anaconda3-2024.10-1-Linux-x86_64.sh bash Anaconda3-2024.10-1-Linux-x86_64.sh -b -p /opt/anaconda3 # 初始化 bash source /opt/anaconda3/etc/profile.d/conda.sh最后那行source .../conda.sh是一个很实用的小技巧:在不执行conda init、不想改动用户.bashrc的场景下(比如临时脚本、CI 环境),直接 source 这个脚本就能让当前 shell 会话获得 conda 命令,退出即失效,非常干净。
2.3 换源与 .condarc 的写法
装完第一件事是换源,否则默认源在国内的下载速度会让你怀疑人生。conda 的配置文件叫.condarc,Windows 上在C:\Users\你的用户名\.condarc,Linux/macOS 在~/.condarc。推荐直接用conda config命令写,比手改文件不容易出格式错误:
conda config --set show_channel_urls yes conda config --add default_channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main conda config --add default_channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r conda config --add default_channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2 conda config --set channel_priority flexible如果你直接编辑文件,.condarc长这样:
channels: - defaults show_channel_urls: true default_channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2 custom_channels: conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud channel_priority: flexible solver: libmamba这里有两个参数值得展开说。channel_priority设为flexible是为了缓解经典求解器那种"卡在 Solving environment 十分钟"的问题;而solver: libmamba是让 conda 使用 libmamba 求解器,速度提升非常明显,新版 conda 已经默认启用,但如果你是从旧版本升级上来的,建议手动确认一下这一行。
pip 也要单独换源,因为它读的是另一套配置。Linux/macOS 写~/.config/pip/pip.conf(老版本读~/.pip/pip.conf),Windows 写%APPDATA%\pip\pip.ini:
[global] index-url = https://pypi.tuna.tsinghua.edu.cn/simple trusted-host = pypi.tuna.tsinghua.edu.cn timeout = 120timeout这个参数容易被忽略,默认 15 秒,装大包(比如 torch 的几个 G)中途超时就前功尽弃了,调到 120 秒稳妥很多。
2.4 安装完成后必须做的五项验证
装完别急着用,先跑一遍自检,把问题扼杀在起步阶段:
# 1. 确认 conda 本体可用 conda --version # 2. 确认 Python 解释器指向 conda 自带的那一个 python -c "import sys; print(sys.executable)" # 3. 查看所有环境及当前激活状态 conda env list # 4. 查看 conda 的配置来源和关键路径 conda config --show-sources conda info # 5. 确认求解器和通道优先级已生效 conda config --show channel_priority solver第 2 步是最关键的。我遇到过不少人conda --version正常,但python指向的是系统里另一个 Python,导致"我明明 conda install 了 pandas,怎么还提示 ModuleNotFoundError"。原因就是 PATH 里有多个 Python,顺序不对。看到sys.executable的路径里带着anaconda3或miniconda3字样才算对。
第 4 步的conda info会打印envs directories和package cache两个路径,重点看它们是不是在同一个盘。如果不在,就按前面说的配一下envs_dirs和pkgs_dirs:
conda config --add envs_dirs D:\conda_envs conda config --add pkgs_dirs D:\conda_pkgs3. 虚拟环境配置:从创建到导入导出的完整链路
3.1 创建环境:版本、命名与位置的取舍
创建环境最常见的命令是这条:
conda create -n proj311 python=3.11 -y参数背后的逻辑值得说清楚。-n后面跟的是环境名,这个名字会被用来做目录名,所以别用中文、别用空格、别用特殊符号。python=3.11是版本约束,conda 会去通道里找一个满足条件的 Python 版本,如果你写python=3它会给你装 3.x 里最新的一个,写python=3.11.5则会精确到小版本。我的习惯是锁到次版本号,比如3.11,这样能在复现性和安全性补丁之间取个平衡。
命名我建议带上项目特征和 Python 版本,比如web311、cv310、nlp312。环境多了以后,conda env list一屏看下来,一眼能分清哪个是哪个,比env1、env2、test这种命名强太多。-y是跳过交互确认,写脚本的时候必加。
如果你不想把环境放在默认的envs目录下,可以用-p指定绝对路径:
conda create -p D:\projects\myproj\env python=3.11 -y这种"项目内环境"的好处是跟项目目录一起管理,删项目的时候顺手带走环境,不会在envs目录里留下一堆孤儿环境。坏处是硬链接可能失效(跨盘),以及conda activate的时候必须给完整路径,不能只给名字。取舍看你的项目管理习惯,我个人的做法是:长期维护的通用环境用-n,一次性实验、临时验证用-p放项目目录里。
创建时还可以一并装包,减少来回操作:
conda create -n proj311 python=3.11 numpy pandas matplotlib scikit-learn -y3.2 激活、切换与退出:为什么你的 conda activate 报错
conda activate proj311这条命令报错,九成以上的原因是 shell 没初始化。具体表现是提示CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'。解决办法前面提过,跑一次conda init <你的shell>然后重开终端。
还有个容易被忽略的点:在脚本文件(.sh、.bat)里直接写conda activate往往不生效。因为脚本执行时会开一个新的非交互式 shell,而conda init写入的初始化代码通常放在.bashrc的交互式分支里,非交互式 shell 不会加载。正确写法是在脚本开头显式 source:
#!/bin/bash source /opt/anaconda3/etc/profile.d/conda.sh conda activate proj311 python train.py这个坑我在写定时任务的时候踩过,crontab里跑 conda 命令一直失败,日志里什么都看不到,加了两行 source 和输出重定向才定位到。
退出环境用conda deactivate,多层的嵌套环境要连续执行多次才能退回 base。查看当前激活状态不要只靠终端提示符(很多人把 PS1 改了,看不到前缀),用conda info --envs,当前环境前面会有一个星号,这个方式最可靠。
3.3 导入 config 配置虚拟环境:environment.yml 的正确导出方式
这是整个流程里最容易出错、也最有价值的一环。所谓"导入 config 配置虚拟环境",本质就是把一个环境里所有包的清单导出成文件,然后在另一台机器或者另一个环境里按这份清单重建。核心命令是conda env export,但它有一个巨大的陷阱。
# 不推荐:导出全部信息,包含平台相关的 build string 和 prefix conda env export > environment.yml这条命令导出的 yml 长这样:
name: proj311 channels: - defaults dependencies: - python=3.11.5=h5b6c2f3_0 - numpy=1.24.3=py311h1f0d5a7_0 - pip: - torch==2.1.0 prefix: D:\anaconda3\envs\proj311问题有三个。第一,build string(也就是=后面那串哈希)是平台和架构强相关的,Windows 上导出的清单拿到 Linux 上重建会直接失败,找不到对应 build。第二,prefix记录了原始路径,对方导入时可能报路径错误,或者环境被建到莫名其妙的地方。第三,包名版本锁得死死的,一些只在小版本上有差异的依赖会互相冲突导致求解失败。
所以正确的导出方式是用--from-history:
# 推荐:只导出你显式指定过的包,不含 build 和 prefix conda env export --from-history > environment.yml导出的内容清爽很多:
name: proj311 channels: - defaults dependencies: - python=3.11 - numpy - pandas - pip - pip: - torch==2.1.0导入的时候:
# 按 yml 重建环境,用 -n 覆盖掉 yml 里的 name conda env create -f environment.yml -n proj311_new如果环境已经存在,想按 yml 增量更新而不是重建:
conda env update -f environment.yml --prune--prune这个参数的作用是删除 yml 里不存在、但环境里实际有的包,让环境严格对齐清单。不加的话只做加法不做减法,环境会越更新越臃肿。用--prune前记得确认清单是完整的,不然会把有用的包删掉,我有一次就因为这个把项目依赖删了一半,重装了四十分钟。
还有一个更严格的复制方式,用于同平台、同架构之间的精确迁移:
conda list --explicit > spec-file.txt conda create --name clone_env --file spec-file.txt这个清单里全是完整的包 URL,能做到逐字节一致,但完全不跨平台,只适合在同型号机器之间批量部署。
至于 pip 依赖,单独维护一份 requirements.txt 也很实用:
pip freeze > requirements.txt pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple注意pip freeze会把环境里所有 pip 安装的包(包括被别的包顺带装上的间接依赖)都写进去,清单会很长但复现最精确。如果你只想要直接依赖,手工维护 requirements.txt 更清爽。
3.4 克隆、重命名、删除与磁盘清理
conda 没有直接的重命名命令,标准做法是克隆再删旧的:
conda create -n proj311_new --clone proj311 conda env remove -n proj311克隆走的是硬链接,速度很快,也不额外占空间(同盘的前提下)。
删除环境之前,先确认它没有被 Jupyter 内核之类的外部引用,后面第 4 节会讲怎么清理。删除命令是conda env remove -n 环境名,注意conda remove -n 环境名 --all也能删,但前者语义更清晰。
磁盘清理是很多人忽略的环节。conda 会缓存所有下载过的包文件和索引缓存,用久了能占几十个 G:
# 清理未使用的包缓存和索引缓存 conda clean -a -y # 查看清理前后的占用 conda clean --dry-run -aconda clean -a会清掉没被任何环境引用的包 tarball 和提取目录,不会影响正在使用的环境,可以放心执行。pip 那边也有缓存,用pip cache purge清理。我大概每两个月清一次,能回收十几个 G,尤其在你频繁试装 PyTorch 不同版本的时候,缓存增长肉眼可见。
4. 多环境并存:让 VS Code、Jupyter 各认各的解释器
4.1 VS Code 的解释器选择与终端自动激活
环境建好之后,真正让新手迷惑的是"VS Code 里到底在用哪个 Python"。VS Code 的 Python 插件会自己扫描环境,但扫描结果不一定是你想要的那个,尤其是环境名重复、存在多个 conda 安装路径的时候。
最直接的方式是用命令面板:Ctrl+Shift+P(macOS 是Cmd+Shift+P),输入Python: Select Interpreter,列表里会列出所有能被识别的解释器,路径里带envs\proj311的那个就是我们要的。选中之后,VS Code 会在项目目录下的.vscode/settings.json里写入记录:
{ "python.defaultInterpreterPath": "D:\\anaconda3\\envs\\proj311\\python.exe", "python.terminal.activateEnvironment": true, "python.analysis.extraPaths": [ "./src" ] }这里每个配置项的作用值得说一下。python.defaultInterpreterPath是默认解释器路径,项目首次打开时按它选。python.terminal.activateEnvironment设为 true,VS Code 打开新终端时会自动执行激活命令,终端里直接就能python xxx.py,不用手动 activate。python.analysis.extraPaths是给静态分析用的,你的源码放在src目录下但导入时用的是包名,不配这项会出现一堆"未解析的导入"波浪线,跑起来其实没问题,但看着烦。
Windows 上有个高频问题:VS Code 的默认终端是 PowerShell,而 PowerShell 没做conda init的话,自动激活会失败,终端里会闪过一行红字提示。解决方案要么按 2.1 节初始化 PowerShell,要么把 VS Code 的默认终端换成 Command Prompt:
{ "terminal.integrated.defaultProfile.windows": "Command Prompt" }我自己的偏好是保持 PowerShell,然后老老实实做一次conda init powershell,因为 PowerShell 在路径处理和脚本能力上确实更好用。
4.2 把 conda 环境注册成 Jupyter 内核
Jupyter 是另一套体系,它不认 conda 环境,只认"内核"(kernel)。你如果不注册内核,jupyter notebook里永远只能看到默认的 Python 3 内核,也就是 base 环境,于是会出现"环境里明明装了包,notebook 里 import 失败"的经典问题。
注册流程是三条命令:
# 1. 激活目标环境 conda activate proj311 # 2. 在该环境里安装 ipykernel conda install ipykernel -y # 3. 注册内核,--name 是内核标识,--display-name 是 Jupyter 界面显示的名字 python -m ipykernel install --user --name proj311 --display-name "Python (proj311)"注册完之后重启 Jupyter,新建 notebook 时就能在 Kernel 菜单里看到Python (proj311)。选它,notebook 就运行在这个环境里了。
管理已注册的内核:
# 查看所有内核及其对应的 json 配置文件位置 jupyter kernelspec list # 删除某个内核(注意这里是内核名,不是环境名,但通常你注册时设成一样的) jupyter kernelspec remove proj311这里有个特别容易忘的点:删掉 conda 环境之后,Jupyter 的内核注册信息还在,你打开 notebook 选那个内核会直接启动失败。所以删除环境的正确顺序是,先jupyter kernelspec remove,再conda env remove。我因为这个顺序问题排查过一次,报错信息是内核启动失败、只有一行模糊的 traceback,找了半小时才发现是残留的内核配置。
如果你用 VS Code 的 Jupyter 插件,它读取的是同一套内核注册信息,所以上面注册一次,VS Code 里也能看到,不用重复配置。
4.3 项目里用 .venv 还是 conda env
这是个经常被争论的问题,我的看法比较明确:看依赖性质。
如果项目依赖全在 PyPI 上、没有复杂的二进制依赖、团队里其他人也用 venv,那就用python -m venv .venv,把环境放在项目目录里,写进.gitignore,和项目同生共死,干净利落。这种方式在 CI 里表现也最好,GitHub Actions 对 venv 有一等公民级别的支持,缓存策略成熟。
如果项目涉及 CUDA、MKL、GDAL、OpenCV 这类需要系统级编译依赖的库,或者需要固定 Python 解释器版本,那就用 conda 环境。conda 装这些包的时候给的是预编译好的二进制,不会出现"pip 装 GDAL 需要先装一堆系统库"这种事。
还有一种折中方案,就是 conda 环境 + 项目内.venv目录并存,用 conda 提供解释器、用 venv 隔离 pip 包。我不推荐这种做法,多一层嵌套只会增加排查难度,除非你有非常明确的理由。
一个实用技巧是把环境配置写进项目的 README 里,包括创建命令和 yml 文件,别人 clone 下来照抄就行:
git clone https://example.com/your-repo.git cd your-repo conda env create -f environment.yml conda activate proj311这样新人上手成本从"研究半天怎么配环境"降到"复制粘贴三条命令"。
5. 踩坑记录与排查速查表
5.1 高频问题速查表
下面这张表是我这些年实际遇到过、并且被问得最多的问题汇总,按报错信息首字母或者关键词排列,方便你按症状查:
| 症状 / 报错信息 | 常见根因 | 处理方式 |
|---|---|---|
conda: command not found | 未初始化 shell,或 PATH 未包含 conda | 执行conda init <shell>并重开终端;或source .../conda.sh |
CommandNotFoundError: Your shell has not been properly configured | 同上,只管了 activate 场景 | 执行conda init,PowerShell 还要放开执行策略 |
Solving environment: failed/ 卡住不动 | 经典求解器性能问题、通道冲突 | 设置solver: libmamba、channel_priority: flexible,减少混用通道 |
PackagesNotFoundError | 包名拼错、通道没加 | 检查拼写;conda config --add channels conda-forge |
| 装了包但 import 失败 | 解释器/内核不是同一个环境 | 打印sys.executable;注册 Jupyter 内核 |
ImportError: DLL load failed(Windows) | 缺少 Microsoft Visual C++ 运行库 | 安装对应版本的 VC++ Redistributable |
| 装包速度极慢或超时 | 默认源、pip timeout 太短 | 换源、timeout=120、加大重试次数 |
| 环境占用磁盘异常大 | 硬链接失效导致复制、缓存未清 | 统一envs_dirs与pkgs_dirs盘符;conda clean -a |
| 导入 yml 失败 | 含 build string 或 prefix、跨平台 | 改用conda env export --from-history |
--prune后依赖缺失 | 清单不完整 | 用完整清单重建,或补全 yml 后重新 update |
5.2 几个容易被忽略的细节(独家避坑)
第一,pip 和 conda 的混用顺序。同一个环境里,先 conda 装能装的包,再 pip 装 conda 装不上的包。反过来的话,conda 的求解器不知道 pip 装了什么,可能会把你 pip 装的包覆盖掉或者降级相关联的依赖。而且导出环境的时候,pip 装的包会单独列在pip:子节点下,顺序乱了对复现没影响,但依赖冲突的影响是实打实的。
第二,conda 环境的激活不等于 pip 的安装目标。我见过有人在 base 环境里pip install,然后激活到目标环境里发现没有包。原因是 pip 的安装目标取决于which pip指向哪里,而有些机器的 PATH 设置会让 pip 一直指向 base。养成习惯:装包前先which python和which pip(Windows 用where python),确认两个路径都指向目标环境。
第三,环境变量在 conda 环境内外不一致。激活环境会重置部分环境变量,尤其是PYTHONPATH和LD_LIBRARY_PATH。如果你在~/.bashrc里设了PYTHONPATH,conda activate 之后可能会被覆盖或清空。遇到"命令行能跑、脚本跑不了"这类玄学问题,先echo $PYTHONPATH对比一下。
第四,别把 base 当工作环境用。base 环境的定位是管理工具本身,你可以在里面装 conda、mamba、conda-libmamba-solver 这类工具,但不要装项目依赖。一旦 base 被你搞坏,修复成本远高于删掉一个普通环境重建。而且我实测下来,base 里包越多,conda env list、conda info这些命令的响应速度越慢。
第五,注意conda activate之后终端提示符的变化。正常情况前面会多一个(环境名),如果没看到但命令能用,说明 PS1 配置被覆盖了,这不影响功能,但会让你失去"我现在在哪个环境"的视觉提示,容易在错误的终端里执行命令。可以用conda info --envs里的星号做二次确认。
最后分享一个我养了很久的习惯:每建一个新环境,第一件事是跑python -c "import sys; print(sys.version, sys.executable)",然后把这个输出记在项目的 README 或者笔记里。环境多了以后,你迟早会遇到"这个模块昨天还能跑,今天怎么不行了"的情况,有一份环境基线记录,回溯问题时能省掉大量猜测。环境配置这件事本身不难,难的是坚持一套一致的规则,不要每次凭感觉来,那样环境越攒越多,最后就是一团谁也理不清的乱麻。