Anaconda 换源这件事,说大不大,说小也不小——从你敲下第一条conda install开始,源选得对不对,几乎决定了后面几个小时的体验是顺畅还是抓狂。最近我把手头几台机器上的 Anaconda 全部切到了交大源(SJTU),过程中顺手记了一堆笔记,越整理越觉得值得单独写一篇。很多教程只告诉你往.condarc里粘一段 YAML,却没讲清楚为什么这么写、什么时候它会失效、失效了该往哪儿查。这篇就从一个常年跟环境打架的普通用户视角,把 Anaconda、交大源、SJTU 这几个关键词背后的东西掰开揉碎讲一遍:从 channel 的工作机制,到.condarc的加载优先级,再到 pip 源为什么必须同步换掉,最后给出一个能直接照抄的完整流程和一份我踩坑踩出来的排查速查表。不管你是刚下载安装 Anaconda 的新手,还是已经能熟练创建虚拟环境的老手,应该都能从里面捞到一两条以前没注意过的细节。
1. Anaconda 换源到底换了什么:先把原理讲透
1.1 channel、repodata 与 pkgs 缓存的三层关系
很多人对换源的理解停留在"换个下载地址",但实际上 conda 的源是一套分层的索引结构。当你执行conda install numpy的时候,conda 并不是直接去某个网址下载一个 numpy 压缩包,它先去每个 channel 拉一份叫repodata.json的索引文件,这个文件里记录了该源下所有包的名字、版本、构建号、依赖关系以及每个包的下载地址和校验值。拿到索引之后,求解器才会在本地做依赖计算,算出该装哪些包,最后才按索引里给的地址去下载实际的包文件。
所以换源换的其实是两样东西:一是索引文件的获取地址,二是包文件的下载地址。这两者在镜像站上通常是同一个域名下的不同路径,改一处就都改了。理解了这一点,你就能明白为什么有些时候明明换了源,conda 还是慢——因为它可能只在新源上找到了索引,但索引里写着的下载地址仍然指向原来的位置;也可能反过来,索引是旧的缓存,压根没去新源拉。
还有一个容易被忽略的角色是本地缓存。conda 会把拉下来的包和索引都存在pkgs_dirs指定的目录里,默认是 Anaconda 安装目录下的pkgs文件夹。这个目录里有一个cache子目录专门放repodata.json。你改了源之后,如果不清这个缓存,conda 有可能继续用旧索引,表现出来就是"配置明明改了,但搜索到的包还是老样子"。这也是后面我要专门讲conda clean -i的原因。
提示:
repodata.json的体积不小,几个主流 channel 加起来动辄几十兆甚至上百兆。国内直连官方源拉这个文件经常卡在"Solving environment"阶段,看起来像死机,实际上是在等索引。换源带来的最大体感提升,往往就来自这一步。
1.2 为什么是交大源(SJTU)而不是别人
国内可选的 conda 镜像不止一家,清华、中科大、阿里云都有,速度其实都不差。我这次统一换到上海交通大学镜像站,主要考虑三点。
第一是目录结构的完整度。交大镜像对 anaconda 的同步把pkgs/main、pkgs/free、pkgs/r、cloud/conda-forge这些常用路径都覆盖了,还有archive目录存放历史版本的安装包。这意味着我不需要为不同 channel 配不同的镜像站,一个域名从头用到尾,.condarc写起来干净。多源混配最容易出的问题就是某个 channel 没同步,装包时突然报PackagesNotFoundError,排查起来很费劲。
第二是路径的规范性。它的 URL 结构和官方 channel 的目录层级基本一一对应,所以可以用channel_alias或者custom_channels这种"整体映射"的写法,而不是把一个个完整 URL 硬塞进channels列表。这个区别很关键:硬塞 URL 的做法,一旦你以后想装某个第三方 channel 的包,还得手动再补一条;用映射的写法,conda 会自动把 channel 名拼到镜像域名后面。
第三是稳定性。镜像站的稳定性不只是"能不能打开",还包括同步频率和断点续传的表现。我在几个不同网络环境下测过,交大源在拉大体积包(比如 CUDA 相关的运行时库,单个几百兆)时中断重试的成功率比较让人放心。当然,镜像站的状态是会变的,具体路径和可用性建议你配置前先去镜像站首页确认一下当前目录,不要完全照着某篇旧文章抄。
需要强调的是,选哪个镜像没有绝对答案,关键是把配置方式搞对。下面这套配置思路,换成别的镜像域名同样适用。
2. 动手之前的三个前置检查
2.1 看清楚自己机器上的 conda 处于什么状态
在改任何配置之前,先做一次体检。打开终端(Windows 用 Anaconda Prompt 或者 PowerShell,Linux 和 macOS 用系统终端),依次执行下面几条命令,把输出记下来。
conda --version conda info conda config --show-sources conda config --show channelsconda --version告诉你 conda 的版本。这个数字比你想的重要——23.10 之后的版本默认换用了 libmamba 求解器,它的行为和老的 classic 求解器有明显差异,包括对 channel 优先级的处理、报错信息的形式、以及内存占用。很多网上搜到的报错解决方案,前提条件就是求解器不同,照抄会失效。
conda info会打印一堆信息,重点看三项:base environment的路径、channel URLs列表、以及package cache dir。channel URLs这一项最能说明问题——它显示的是 conda 当前实际会去请求的地址,而不是你配置文件里写了什么。配置文件写了但没生效的情况太常见了,以这个输出为准。
conda config --show-sources则会告诉你当前生效的配置分别来自哪些文件。正常情况你会看到用户目录下的.condarc;如果还冒出来系统级的配置文件或者环境变量指定的路径,就要留意优先级问题,这是下一节的内容。
注意:如果你在
conda info里看到channel URLs包含repo.anaconda.com这样的地址,说明还在走默认源。有些新版安装包自带了一份默认配置,光改用户级.condarc未必盖得住。
2.2 .condarc 的加载顺序决定了你的改动生不生效
.condarc是一个 YAML 格式的配置文件,conda 会按固定顺序从多个位置读取并合并它们,后面的覆盖前面的。大致顺序是:安装目录下的系统级配置、环境变量CONDARC指向的文件、用户主目录下的用户级配置、最后是命令行参数。Windows 上用户级配置在C:\Users\你的用户名\.condarc,Linux 和 macOS 在~/.condarc。
这里有两个坑特别常见。一是 Windows 上这个文件没有文件名只有扩展名,用记事本保存的时候容易变成.condarc.txt,看起来一样,实际完全没被读取。正确的做法是在保存对话框里把文件名用英文双引号包起来写成".condarc",或者干脆用 VS Code、Notepad++ 这类编辑器另存为,显式指定文件名。
二是 YAML 的缩进必须用空格,绝对不能用 Tab。YAML 对缩进敏感,一个 Tab 就能让整个文件解析失败,而 conda 在某些情况下不会明确报错,只是默默忽略这份配置,然后你就在那儿纳闷为什么改了半天没反应。另外文件编码建议用 UTF-8 且不带 BOM,带 BOM 的文件在部分版本上会解析异常。
还有一个细节:列表项的写法。channels是一个列表,每一项前面要加-,并且-后面要有一个空格。写成-https://...或者- https://...(两个空格)都可能出问题。这种小地方出错,排查成本极高,因为报错信息通常不会指向缩进。
2.3 网络与权限:容易被忽略的两个变量
网络层面,先确认你的机器有没有设置代理类的环境变量。有些公司网络或者某些软件会在系统里留下HTTP_PROXY、HTTPS_PROXY、ALL_PROXY这类变量,conda 会读取它们。这时候即使你把源指向了国内镜像,请求也可能被这些变量劫持到别的地方去,出现连不上或者证书错误。用echo $HTTPS_PROXY(Linux/macOS)或者echo %HTTPS_PROXY%(Windows)看一眼,如果有值而且你并不需要,临时清掉再试。
另外,如果你在容器或者服务器上操作,注意 conda 的安装位置是不是在只读挂载点上。.condarc写不进去,配置自然不生效。同理,pkgs_dirs如果指向一个没有写权限的目录,conda 连索引缓存都存不下,每次都要重新拉,慢得毫无道理。
权限方面还有个小问题:某些系统上 Anaconda 是用管理员权限装到/opt或C:\ProgramData下的,普通用户对这些目录只有读权限。这种情况下不要尝试去改安装目录里的系统级配置,老老实实在用户目录下写.condarc,让用户级配置覆盖掉默认行为就好。
3. 交大源的完整配置实操
3.1 命令行方式:一行一行 add 进去
最直观的方式是用conda config --add channels一条条加。命令长这样:
conda config --add channels https://mirror.sjtu.edu.cn/anaconda/pkgs/main/ conda config --add channels https://mirror.sjtu.edu.cn/anaconda/pkgs/free/ conda config --add channels https://mirror.sjtu.edu.cn/anaconda/cloud/conda-forge/ conda config --set show_channel_urls yes注意--add是把新项加到列表最前面,也就是说后加进去的优先级更高。所以如果你希望某个 channel 优先被搜索,就把它放在最后 add。这个顺序逻辑和很多人的直觉相反,我第一次用的时候也绕了一下。
show_channel_urls yes的作用是让 conda 在安装和搜索时打印出每个包来自哪个 channel。这个选项强烈建议常开,它是我排查问题时的第一手信息来源——一眼就能看出包到底是从镜像下的还是从默认源下的。
命令行的好处是不用手写 YAML,不容易出格式错误;缺点是当你要配置的 channel 很多时,命令会变得很长,而且以后想整体替换镜像站,得先把旧的一条条 remove 掉,比较繁琐。另外,如果你的.condarc里已经有defaults这个 channel 名,光加镜像 URL 是不够的,defaults仍然会解析到官方地址。
3.2 手写 .condarc:我更推荐的稳妥做法
折腾过几轮之后,我固定用下面这份配置。它的核心思路不是把完整 URL 塞进channels,而是用default_channels和custom_channels做整体映射——这样你日常的安装命令一个字都不用改,conda install -c conda-forge xxx这种写法会自动走到镜像上。
channels: - defaults default_channels: - https://mirror.sjtu.edu.cn/anaconda/pkgs/main - https://mirror.sjtu.edu.cn/anaconda/pkgs/r - https://mirror.sjtu.edu.cn/anaconda/pkgs/msys2 custom_channels: conda-forge: https://mirror.sjtu.edu.cn/anaconda/cloud pytorch: https://mirror.sjtu.edu.cn/anaconda/cloud nvidia: https://mirror.sjtu.edu.cn/anaconda/cloud show_channel_urls: true ssl_verify: true几点说明。default_channels的作用是重新定义defaults这个逻辑 channel 到底指向哪些物理地址,这是替换官方默认源最干净的做法。custom_channels则是给具名 channel 指定镜像前缀,conda 会把conda-forge、pytorch这些名字拼接到你给的域名后面,形成完整路径。
这里有个取舍要讲清楚:custom_channels里能列多少 channel,取决于镜像站同步了哪些目录。上面这几条是我确认过存在的,但镜像站的目录结构会调整,你配置前务必去站点上看一眼实际路径。如果某个 channel 没有同步,conda 在需要它的时候会报 404 或者找不到包,那时候把对应的那行删掉就行,不影响其他配置。
defaults这一项保留在channels列表里是刻意的。因为很多第三方包的依赖里写死了defaults,如果列表里没有这个名字,conda 有时候会绕开你的映射去直接访问官方地址。保留它、同时用default_channels改掉它背后的实际地址,是兼容性最好的组合。
提示:改完
.condarc后不要急着装东西,先跑一遍conda config --show channels和conda info,确认输出的 URL 已经变成镜像地址。配置文件写对了但没生效,十有八九是文件名、编码或者缩进的问题。
3.3 清索引缓存并验证换源是否真正生效
配置改完之后必须清一次索引缓存,这一步不能省:
conda clean -i conda clean -y --all第一条-i专门清repodata.json这类索引缓存,是换源后的必做动作。第二条会把下载的包缓存、压缩包等一并清掉,能腾出不少空间,代价是下次装包要重新下载。如果你磁盘紧张,或者怀疑某个包缓存损坏了,就执行完整清理;如果只是想验证换源效果,第一条就够了。
验证方式我一般用两种。一种是搜索一个包看输出里的 URL:
conda search numpy输出表格里会有一列显示 channel 地址,配合show_channel_urls: true,你能直接看到它是不是从mirror.sjtu.edu.cn来的。
另一种是干跑一次环境创建,观察它会去哪些地址拉索引:
conda create -n _probe python=3.11 --dry-run--dry-run只做求解和下载计划,不真的落地。如果这一步能很快跑完,而且打印出来的地址都是镜像域名,说明配置到位了。验证完把_probe这个临时环境删掉即可:conda env remove -n _probe。
实测下来,换源前后最明显的差别就在Solving environment这个阶段。以前直连官方源经常要等一两分钟甚至直接超时,换成交大源之后基本在十秒内出结果。这一步省下来的时间,一天下来相当可观。
4. pip 源要一起换,不然等于半途而废
4.1 conda 和 pip 在两套索引上并行工作
这是最容易被忽略的一点:conda 和 pip 走的是完全独立的两套索引系统。你把 conda 的源换得再干净,只要动手pip install,它照样去默认的 PyPI 服务器拉包。而在国内直连 PyPI 的体验,用过的人都知道——下载速度不稳定,偶尔直接超时。
更麻烦的是混合使用带来的隐性成本。很多人第一次装 PyTorch 或者 TensorFlow 的时候,会先conda install装一部分,然后发现某个包 conda 源里没有,又用pip install补上。这时候如果 pip 慢,你会误以为是 conda 源的问题,跑去反复改.condarc,改了半天没效果。实际上问题出在另一条完全独立的链路上。
所以我的原则是:这俩必须一起换,配置一次省心很久。
4.2 交大 PyPI 镜像的配置与验证
pip 的配置方式有好几种,优先级从高到低大致是命令行参数、环境变量、用户级配置文件、全局配置文件。我一般用用户级配置文件,跨平台通用。
Linux 和 macOS 上,命令方式最省事:
pip config set global.index-url https://mirror.sjtu.edu.cn/pypi/web/simple pip config set global.trusted-host mirror.sjtu.edu.cnWindows 上同样可用,pip config会自动写到%APPDATA%\pip\pip.ini。如果你想手写文件,Linux/macOS 放在~/.pip/pip.conf,Windows 放在%APPDATA%\pip\pip.ini,内容如下:
[global] index-url = https://mirror.sjtu.edu.cn/pypi/web/simple trusted-host = mirror.sjtu.edu.cn timeout = 60timeout这一项单独说一下。默认超时时间比较短,下载大包的时候如果网速波动,容易中途断掉然后重试,重试又从头开始,体验很差。设成 60 秒能缓解不少。trusted-host在 HTTPS 正常的情况下其实不是必须的,但有些环境里的证书链不完整,加这一行能避免 SSL 报错,属于保险措施。
验证方式很简单,随便装个小包看输出里的下载地址:
pip install --upgrade pip pip install requests -v-v会打印详细的请求地址,你能看到它去的是不是镜像站。另外pip config list可以列出当前所有生效的配置,排查时很有用。
4.3 conda 与 pip 混用的边界
换源只是让下载变快,它解决不了 conda 和 pip 混用带来的依赖管理问题。这里分享几条我自己遵守的规矩。
第一条,能用一个渠道解决就别混。一个环境里优先全部用 conda 装,只有 conda 源里确实没有的包才用 pip 补。原因是 conda 会维护一份环境级别的依赖记录,pip 装进去的包它不完全知情,后面再用 conda 装东西时,求解器可能会把你 pip 装的包覆盖掉或者搞出冲突。
第二条,绝对不要在 base 环境里做实验。base 环境是 conda 自己的运行基础,里面装了 conda 本体和一堆支撑库。在 base 里乱装包,轻则导致 conda 自己启动变慢,重则直接把 conda 搞坏,最后只能重装。我现在的习惯是 base 环境只保留最基础的东西,所有项目都建独立虚拟环境。
第三条,如果一个环境里既有 conda 装的包又有 pip 装的包,建议在environment.yml里把 pip 那部分单独列在pip:子节点下,这样重建环境的时候顺序不会乱:
name: myproj channels: - defaults dependencies: - python=3.11 - numpy - pip - pip: - some-pypi-only-packageconda 会先装上面的部分,再执行 pip 那一节,顺序是有保证的。
5. 换完源之后,用一个真实环境跑通全流程
5.1 创建独立虚拟环境并锁定 Python 版本
光换源不算完成,得用一个真实项目验证整条链路。我拿配置 PyTorch 环境这个最典型的场景来走一遍。
conda create -n torch_sjtu python=3.11 -y conda activate torch_sjtu关于 Python 版本的选择,这里有个实际考量。新版本的 PyTorch 通常只支持较新的 Python,而一些老项目的依赖又卡在旧版本上。3.11 是我目前在兼容性和新特性之间觉得比较舒服的点,但你应该根据自己的项目依赖来定。如果拿不准,可以先建一个环境装一个依赖最重的包试试,报错信息里通常会明确告诉你它支持哪些 Python 版本。
激活之后确认一下环境是否真的切换了:
python --version which python # Windows 上用 where python输出应该指向envs/torch_sjtu/下的 python,而不是 base 环境或者系统自带的。如果还是系统的 Python,说明激活没生效,检查一下conda init有没有执行过。
5.2 安装 PyTorch 时的命令拆解与参数含义
PyTorch 的官网会生成一条安装命令,形态大致是这样:
conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia这条命令里的每个部分都有讲究。pytorch、torchvision、torchaudio是三个主包,版本上最好让 conda 自己去解,除非你有明确的版本要求。pytorch-cuda=12.1这个参数指定的是编译时链接的 CUDA 运行时版本,注意它不等于你系统装的 CUDA Toolkit 版本——conda 会把需要的运行时库一起装进环境,和你系统里有没有 CUDA 没关系,你只需要保证显卡驱动足够新。
-c pytorch -c nvidia指定了额外的 channel。这两个 channel 在国内默认访问也很慢,所以我在前面.condarc里用custom_channels把它们一起映射到了镜像。如果镜像站没有同步这两个 channel,你会看到PackagesNotFoundError,这时候的处理办法有两种:一是去镜像站确认对应目录是否存在,二是改用 pip 安装(PyTorch 官方也提供 pip 渠道)。
安装体积要有心理准备,CUDA 相关的运行时库加起来可能好几个 G。这一步最考验源的稳定性,也是我最推荐换源的原因——直连的时候这里经常断,断了重试又要重新解析依赖。
装完之后验证:
python -c "import torch; print(torch.__version__); print(torch.cuda.is_available())"如果第二行输出False而你确实有 NVIDIA 显卡,先别急着怀疑源的问题,大概率是驱动版本或者装成了 CPU 版本。用conda list | grep torch(Windows 上用findstr)看一下装上的包名,CPU 版本的包名里通常带cpu字样。
5.3 把环境挂到 PyCharm 上
环境装好了,最后一步是让编辑器用上它。PyCharm 里的路径是:打开项目后进入设置,找到项目解释器那一栏,点添加解释器,选择 Conda 环境,然后选"使用现有环境",在解释器路径里指向你的环境目录。
具体路径长这样:
| 平台 | 解释器路径 |
|---|---|
| Windows | C:\Users\用户名\anaconda3\envs\torch_sjtu\python.exe |
| Linux | /home/用户名/anaconda3/envs/torch_sjtu/bin/python |
| macOS | /Users/用户名/anaconda3/envs/torch_sjtu/bin/python |
如果你在 Windows 上装 Anaconda 时选了"仅为我安装",路径会在用户目录下;如果选的是"所有用户",可能在C:\ProgramData\Anaconda3。用conda env list可以打印出所有环境的准确路径,比凭记忆找靠谱。
配置好之后,PyCharm 底部的终端会自动激活这个环境,你在终端里conda install装的包,编辑器里立刻就能 import。这一步如果没生效,检查 PyCharm 里的终端设置有没有勾选自动激活虚拟环境。
6. 踩过的坑:常见报错与排查速查表
6.1 索引类报错:JSONDecodeError、CondaHTTPError
换源之后最常见的两类报错都跟索引有关,症状不同,原因也往往不一样。
JSONDecodeError: Expecting value: line 1 column 1 (char 0)的意思是 conda 拿到了repodata.json,但内容不是合法的 JSON。最常见的原因是本地缓存的索引文件损坏,或者某次请求被网络中间层拦截返回了一个 HTML 错误页。处理办法是先清索引缓存再重试:
conda clean -i conda update --all如果清完还报同样的错,就要怀疑镜像站那个目录当时是不是有问题,换个时间点或者临时切回另一个镜像验证一下,能快速定位问题在哪一侧。
CondaHTTPError: HTTP 403 FORBIDDEN或者HTTP 404 NOT FOUND通常是路径写错了。前面说过,镜像站的目录结构会调整,你照着旧文章抄的路径可能已经变了。解决办法是打开镜像站首页,一层层点进去看pkgs/main这些目录到底在不在,把.condarc里的地址改成实际存在的。
SSLError这类证书问题,先确认你系统的时间是不是准的——时间偏差过大会导致证书校验失败,这个原因很隐蔽。确认时间没问题之后,再检查有没有代理类环境变量干扰。
6.2 明明换了源却依然慢:几个隐蔽原因
下面这张表是我自己遇到过、也帮别人排查过的几种情况,按出现频率排序:
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
conda info里仍是官方地址 | 配置文件名或编码有问题 | 确认是.condarc,UTF-8 无 BOM |
| 搜索包很快,下载包很慢 | 索引走了镜像,包地址仍是官方 | 检查default_channels是否配全 |
| 每次都要重新拉索引 | pkgs_dirs无写权限 | 检查目录权限或改到可写位置 |
| 部分包找不到 | 镜像未同步该 channel | 换用官方源单独装,或换镜像 |
| 求解阶段极慢 | 求解器或依赖冲突 | 尝试切换求解器,或放宽版本约束 |
| 请求被劫持到奇怪地址 | 代理类环境变量 | 临时清除后再试 |
| 报错指向旧文件路径 | 索引缓存未清 | 执行conda clean -i |
这个表里的第一行和第四行是最值得记住的。前者占了"改了没效果"问题的一大半,后者则是镜像方案的固有局限。
注意:不要为了让 SSL 通过就把
ssl_verify设成false。这会让所有下载失去校验,属于拿安全换便利,得不偿失。真遇到证书问题,正确做法是把企业根证书配到 conda 的证书路径里。
6.3 求解器与环境层面的疑难杂症
症状是Solving environment卡很久然后失败,或者依赖报错看起来莫名其妙。这时候可以试试换求解器。新版 conda 默认用 libmamba,速度快但对某些老 channel 的兼容性略差;老版默认的 classic 慢一些但更宽容。
conda config --set solver classic conda config --set solver libmamba命令行也可以临时指定:conda install xxx --solver=classic。排查时先临时切换试试,确定了再写进配置。
另一个高频问题是环境被装坏了。典型的信号是import某个包时报错,或者 conda 自己启动都变慢。这时候与其花时间修,不如导出依赖重建:
conda env export -n 坏掉的环境 > backup.yml conda env remove -n 坏掉的环境 conda env create -f backup.yml导出的yml里会包含具体的版本号,重建出来的环境和你原来的一致。如果重建也报错,把yml里写死版本的那些行删掉,让 conda 重新求解,通常就能绕过某个不再可用的旧版本。
还有一种情况是环境列表里出现了一些名字很奇怪的环境,比如带__前缀的。这些通常是 conda 安装过程中的临时环境或者没清理干净的残留,可以用conda env remove删掉,不影响正常使用。
7. 长期维护:让这套配置一直好用
7.1 镜像同步滞后时的应对策略
镜像站本质上是官方源的一份拷贝,同步有延迟是必然的。表现就是某个刚发布不久的新版本,官方源已经有了,镜像上还查不到。这时候有几个选择。
最直接的是等一两天,多数情况下热门包同步很快。如果项目紧急,可以临时指定官方源装那一个包,装完不要把它写进.condarc:
conda install -c defaults 某个包但要注意,一旦命令里显式写了-c defaults,而你又在.condarc里把defaults映射到了镜像,它走的还是镜像。真要临时走官方源,得用完整 URL 指定,或者临时把配置改回来,用完再改回去。所以更推荐的做法是准备一份备用配置文件,切换时用CONDARC环境变量指向不同的文件,比反复编辑同一个文件安全。
还有个思路是降低对最新版本的执念。生产项目里锁定的版本号本来就不应该追新,镜像的同步延迟对这类项目几乎没有影响。真正受影响的只有那种"必须复现最新论文代码"的场景。
7.2 版本升级、卸载与重装时的注意事项
升级 conda 本身是一个容易翻车的操作。推荐用conda update -n base -c defaults conda,但如果你在.condarc里把defaults映射到了镜像,这里的-c defaults会走镜像,一般也没问题。升级过程中千万不要中断,中途打断有概率把 base 环境搞坏。
如果你需要彻底卸载重装,Windows 上可以用安装目录里的卸载程序,卸载后记得手工检查并清理几个残留位置:用户目录下的.condarc、.conda文件夹、以及%APPDATA%下的 pip 配置。Linux 和 macOS 一般是直接删掉安装目录,再把 shell 配置文件(.bashrc、.zshrc)里 conda 初始化添加的那一段删掉。不清理 shell 配置的话,重装之后会出现两个 conda 打架的情况,终端里which conda指来指去,特别烦。
安装新版本的时候,Windows 上有个选项问你要不要加入 PATH,我的建议是不要勾,让 conda 通过conda init自己管理 shell 初始化。手动加 PATH 容易和系统里其他 Python 冲突,而且加了之后很多环境激活的逻辑会变复杂。
最后一点经验:把这份配置和依赖导出文件一起放进版本管理里。.condarc的内容不多,但它决定了一台新机器上环境能不能顺利搭起来。我现在的做法是项目仓库里放一个environment.yml,个人机器上再单独维护一份.condarc的备份,换机器的时候两个文件一贴,半小时能把整套开发环境恢复出来,比自己凭记忆重新配一遍靠谱得多。
我个人在实际操作中的体会是,换源这件事的价值不在于省下那几分钟下载时间,而在于它把"环境配置"从一件充满随机性的事,变成了一件可预期、可复现的事。以前帮别人远程看问题,第一句总得问"你先装个什么试试",现在直接让他把.condarc的内容发过来看一眼,问题基本就定位了一半。另外提醒一句,如果你手头有多个项目跨好几个 Python 版本,别偷懒共用环境,多建几个虚拟环境占不了多少磁盘,但能省掉大量排查依赖冲突的时间——这个账我算过,怎么都是划算的。