☰
新版conda创建Python 3.7环境全指南:报错排查与共存方案
2026/10/14 4:44:57 网站建设 项目流程

如果你的项目配置文件里写着requires-python = ">=3.7,<3.8",或者团队里某个老模块只能在 py3.7 下跑通,而你电脑上的 conda 又是新装的——那你大概率见过这个报错:PackagesNotFoundError: python=3.7。先说结论:conda 本身完全支持创建 Python 3.7 环境,你不需要给 conda 降级,更不需要重装系统 Python。真正的坑在于 channel 配置、依赖解析方式,以及 py3.7 进入 EOL 之后仓库里可用包越来越少,很多人就把这个误判成了“conda 不支持 py3.7”。这篇文章围绕“让 conda 支持 py3.7”这个目标,把从环境创建、依赖安装到高频报错的完整排查链路都过一遍,适合被老项目绑住手脚、又不想动 conda 底层配置的开发者,也适合刚入门 conda 但被各种“找不到包”吓住的新手。

1. 一堆人卡在“conda 不支持 py3.7”的真正原因

1.1 你其实混淆了“conda 版本”和“Python 版本”

我经常看到类似问题:“我装的是最新版 Miniconda,为什么它不支持 Python 3.7?”这句话里面有个很常见的误解:把 conda 自身的 Python 版本,和 conda 能管理的 Python 版本混到了一起。

conda 是一个包管理和环境管理工具。它运行在某个 Python 解释器上,通常就是 base 环境里那个 Python。但 base 环境的 Python 版本,只代表 conda 自身跑在什么版本上,不代表 conda 只能创建这个版本的环境。举个几乎每天都会发生的例子:你的 Miniconda base 是 Python 3.12,但你可以直接在里面创建一个 Python 3.7 环境,两者互相不干扰。如果你误以为“我得先把 conda 降到 py3.7”,然后跑了一句conda install python=3.7,那才是真的把 base 环境玩坏了——conda 会开始把 base 里的所有依赖降级,甚至可能降到一半就崩溃。

所以“让 conda 支持 py3.7”的第一层正确理解是:让 conda 具备创建和运行 Python 3.7 环境的能力。新版 conda 不需要降级,它通过 channel 仓库去拉取 Python 3.7 的包。只要仓库里还有 Python 3.7 的元数据(repodata.json里仍然包含 3.7 的构建记录),conda 就能创建出对应的环境。Python 3.7 在 2023 年 6 月之前属于正常维护期,之后进入了 EOL(End of Life,停止官方维护)。官方虽然不修 bug 了,但 conda-forge 和默认仓库里历史包仍然保留着,所以现在依然可以用 conda 创建 py3.7 环境,只是可选的新包越来越少。

我自己的实测结果:conda 24.x 在全新配置下执行conda create -n py37 python=3.7,只要 channel 配置里包含默认的repo.anaconda.com/pkgs/main或者conda-forge,基本都能成功。前提是你没有把 channel 改成只剩下一个过期的私有源。

1.2 真正需要 py3.7 的场景:老项目、老论文、老流水线

很多人会问,2025 年了为什么还有人要 py3.7?我归类下来无非三种典型情况。

第一种是旧项目锁死。比如某个内部系统的依赖链里有个包只在 Python 3.7 下编译过,升到 3.8 就会缺 C 头文件,或者某个核心库的接口行为变了,导致线上模块跑了几年的逻辑报错。你问为什么不修?因为修改成本大、风险高,而且可能没有对应的维护人员。

第二种是复现老论文、老代码。很多开源项目是好几年前写的,仓库里的requirements.txt写的是pytorch==1.7.1、tensorflow==2.4之类。这些老版本对 Python 3.7 的支持最完整,你拿到新 conda 环境里装新版 Python,再 pip install,经常得到的结果是“找不到匹配版本”,或者装完了导入直接报 C 扩展不兼容。

第三种是 CI/CD 流水线对齐。公司某条发布流水线的镜像基于python:3.7构建,本地开发环境必须和它保持完全一致,否则本地测得好好的,一上流水线就炸。

想清楚自己属于哪种情况很有必要,因为后面所有操作都基于这个目标:你只是临时跑一个老脚本,还是想长期维护一个 py3.7 环境,还是想把某台机器上的 py3.7 环境完整迁到新机器?三种需求的处理策略完全不同。临时用就直接创建环境装依赖;长期用需要固定 channel 和依赖版本;迁移则优先用conda env export而不是手工重新拼环境。

2. 让 conda 支持 py3.7 的三条可行路径

2.1 路径一:不改 conda,直接创建 py3.7 环境

这条路径适合绝大多数人,也是我最推荐的。不需要降级 conda,不需要重新安装,核心就一条命令:

conda create -n py37 python=3.7

这一行会让 conda 在当前配置的 channel 里寻找 python 3.7 的包,然后创建一个名为py37的独立环境。后续你想装什么包,直接追加到命令里也行,或者环境建好之后用conda install。

conda create -n py37 python=3.7 numpy pandas

如果你执行之后报错说找不到python=3.7,那 90% 是 channel 配置问题,不用慌,后面第 4 节会详细讲排查链路。先剧透一个常见解法:加一个conda-forge通道再试。

2.2 路径二:安装与 py3.7 同期的旧版 Miniconda

如果路径一确认怎么都跑不通,而且你确实需要让“conda 本体”就跑在 py3.7 上(比如做打包测试或者复现某个历史环境),那可以考虑装一个 Python 3.7 时代的旧版 Miniconda 安装包。那个包里的 base 环境本身就是 Python 3.7,conda 版本也比较老,天然就和 py3.7 “绑定”了。

但这条路有两个新问题要提前知道。

第一,老版本 conda 的 SSL 证书库已经落后,访问现在的官方源或者镜像源时,经常出现 HTTPS 证书校验失败。需要手动升级certifi,甚至临时关闭校验,操作成本不低。

第二,老版本 conda 的依赖解析效率很差。你用它装一个新包,可能在 “Solving environment” 这个阶段卡很久,因为默认的经典 solver 是回溯式解析,依赖一多就指数爆炸。

我的建议非常明确:除非你的目标本身就是要“整个 conda 在 py3.7 上跑”,否则路径二不要选。它看起来是“让 conda 支持 py3.7”的字面解法,实际上日常维护成本远高于路径一。

2.3 路径三:从已有 py3.7 环境导出 YAML 再重建

如果你手边已经有一台机器,上面有一个跑得好好的 py3.7 conda 环境,现在需要把它复制到新机器,那千万别一个个手工装包,用导出重建的方式最稳。

conda env export -n py37 > py37_env.yaml

把生成的py37_env.yaml拷贝到目标机器上执行:

conda env create -f py37_env.yaml

这条路线的精髓在于:导出文件里保存了环境里每个包的精确版本号、构建号和来源 channel,能最大程度复现原环境。不过注意,导出文件里有些字段可能带原机器的平台信息,跨平台迁移时(比如从 Linux 迁到 macOS),经常报package not available for platform。碰到这种情况,把 yaml 里的source和build字段删掉,只保留name、channels、dependencies,再重新执行。

对比一下,路径一适合从零起步,路径三适合环境复制。两种方案可以互补,但路径三对 py3.7 这种“越来越老”的环境尤其好用——因为老的依赖组合一旦被源站下架,手工重新解析几乎不可能成功,只有锁死版本的导出文件才能复现。

3. 手把手实操:创建 py3.7 环境的完整流程

3.1 检查现状:conda 版本与 channel 配置

动手之前,先摸清家底。三个命令就够了:

conda --version conda config --show channels conda config --show channel_alias

conda --version让你知道自己的 conda 版本。一般 conda 4.6 以上都没问题,现在新装的通常都是 23.x 或者 24.x。channels是当前生效的 channel 列表,注意它的顺序很重要,conda 会按顺序去仓库里找包。channel_alias是默认的源地址前缀,国内用户往往会把它改成镜像地址。

如果 channels 里既没有defaults也没有conda-forge,只有某个实验性 channel,那后面找不到python=3.7是再正常不过的事。先补 channel 再继续。

3.2 修改 channel 优先级并创建环境

为了保证能拉到 py3.7 的包,我会把conda-forge加到 channel 列表里,同时把优先级设为flexible,而不是strict:

conda config --add channels conda-forge conda config --set channel_priority flexible

这里有个重要细节:如果你把channel_priority设为strict,conda 会从优先级最高的 channel 里找所有包,一旦defaults和conda-forge对某个依赖包的历史版本管理不一致,解析很容易失败或者卡死。flexible模式更宽松,conda 会自己权衡,找到能用的组合。

然后执行:

conda create -n py37 python=3.7 -y

如果你不想改全局 channel 配置,只打算试一次,可以直接在命令里指定 channel:

conda create -n py37 -c conda-forge python=3.7

-c conda-forge只对这一次创建生效,不会污染全局配置。我个人倾向于这个方式,能保持环境创建的“单次性和可复现性”,但如果你以后经常需要 py3.7 环境,调整全局配置更方便。

3.3 环境验证与 pip 版本落地

环境创建成功后,先别急着装包,把下面四件事确认了:

conda activate py37 python --version pip --version which python

python --version应该显示3.7.x系列。pip版本如果特别低,比如 9.x、10.x,可以先升级,但要小心这里埋了一个大坑:pip 23.3.2 是最后一个支持 Python 3.7 的 pip 版本。从 pip 23.4 开始,pip 直接放弃了对 Python 3.7 的兼容,你在 py3.7 环境里跑pip install --upgrade pip,装上的会是一个无法正常运行的 pip,之后所有 pip 命令都会报错。所以升级 pip 一定要带版本上限:

pip install "pip<23.4"

还有一点,which python必须指向envs/py37/bin/python(Windows 上是envs\py37\python.exe)。如果它指向系统自带的/usr/bin/python,说明环境没有真正激活,后面装包会装到系统 Python 的 site-packages 里,环境隔离就失效了。

3.4 将 py3.7 设为一个项目的默认解释器

环境建好之后,日常使用有两种方式。第一种是每次开发前先手动conda activate py37,简单直接。第二种是把项目 IDE 的默认解释器指向这个 conda 环境。以常见 IDE 为例,一般在项目设置里选择 “Python Interpreter”,然后指定路径~/miniconda3/envs/py37/bin/python。

这里最容易出的问题是:IDE 里明明是 py3.7 解释器,但命令行跑起来又是另一个版本。原因通常是终端里的 shell 没有执行conda init,导致 conda 环境变量没注入。底层逻辑是conda activate本质上修改了PATH环境变量,把envs/py37/bin放到最前面,如果你在 shell 里敲python,系统查到的就是环境里的解释器。但 IDE 启动方式不同,它不一定读取你终端的环境变量,所以手工指定解释器路径反而更可靠。

验证方法也简单:在项目目录执行which python,确认结果是envs/py37/bin/python,再运行几行代码看看sys.version_info是否匹配。

4. 高频报错的完整排查链路

4.1 PackagesNotFoundError:channel 没找对

这是“让 conda 支持 py3.7”路上最常见的报错,典型输出长这样:

PackagesNotFoundError: The following packages are not available from current channels: - python=3.7

我第一次遇到时也以为是 conda 坏了。后来总结出一套排查顺序,按这个顺序走基本都能解决:

  1. 执行conda config --show channels,看 channel 列表里有没有defaults或conda-forge。如果没有,先加上。
  2. 直接在浏览器里访问官方仓库的 repodata,搜索 Python 3.7 的构建记录是否还存在。比如去https://repo.anaconda.com/pkgs/main/linux-64/repodata.json,正文里搜python-3.7,能看到包记录就说明源头没问题。
  3. 确认平台标签。如果你的电脑是 Apple Silicon,conda 默认架构可能是osx-arm64,而有些历史包只有osx-64版本。这时候要确认 conda 是以 arm64 原生运行,还是通过 Rosetta 转译,两者的 channel 路径完全不同。
  4. 检查是否装了定制版 conda,渠道商会覆盖 channel 配置。某些企业版或者文档里特别配置过的 conda 会清掉默认源,手动把defaults加回来即可。

这个报错的根因不是“conda 不支持 py3.7”,而是 conda 严格按照 channel 列表的顺序去找包。你把一个私有源放在最前面,私有源里没有 py3.7,conda 不会自动跳到defaults里补救,而是直接报 not available。解决方式就是把defaults或conda-forge放前面,或者创建环境时用-c conda-forge显式指定。

4.2 依赖冲突:conda solve 卡死的两个原因

创建 py3.7 环境时如果同时指定一堆包,比如python=3.7 numpy pandas scikit-learn matplotlib,可能会在 “Solving environment” 阶段卡特别久,甚至看着像死机。这里有两个完全不同的原因,但症状差不多。

第一个原因是默认的 classic solver 效率太差。老版本 conda 的依赖解析工具是回溯式的,遇到复杂依赖组合会疯狂试探,最夸张的时候一个 20 包环境可能卡十分钟。解法是启用新 solver:

conda install -n base conda-libmamba-solver conda config --set solver libmamba

conda 23.10 以上版本默认已经启用 libmamba,老版本装一下这个包就行。装了 libmamba 之后同样的命令通常十几秒就能出结果。

第二个原因更隐蔽:你用的不是新建环境,而是在一个已有环境里执行conda install python=3.7。已有环境里的包依赖可能本来就需要 Python 3.8+,conda 要新装一个 py3.7 的同时还要重算所有旧依赖,这种“降级式安装”很容易无解。正确操作永远是新建独立环境,别在旧环境里强拉版本。

4.3 SSL/下载失败:源和证书问题

国内用户经常遇到下载超时或者 SSL 错误,报错一般是CondaHTTPError: SSL certificate verify failed或者Connection timed out。

如果是 SSL 证书报错,大概率是 conda 自带的certifi太旧,尤其当你使用 conda-forge 源时,证书校验比较严格。修复方式:

conda update -n base conda certifi

如果你连 base 环境都进不去,没法执行上面的命令,那就临时允许不安全连接(只用于下载,不要长期开启):

conda create -n py37 -c conda-forge python=3.7 --no-config

或者设置环境变量CONDA_SSL_VERIFY=false。这个应急方法只建议在环境创建阶段用,创建完成后处理掉环境变量。下载慢的问题,稳妥做法是配置镜像源,把 channel 地址替换成镜像站的 HTTPS 地址。但注意:有些镜像只同步最新包,老版本可能要等同步周期,如果镜像源里没有 py3.7 的包,就切回官方源,官方源慢但全。

4.4 激活环境后 python 仍是旧版本

还有一个很容易让人崩溃的现象:conda activate py37后,python --version显示的依然是系统自带的版本,不是 3.7。

判断方法,先看环境变量:

echo $CONDA_PREFIX

如果显示的是envs/py37,说明 conda 认为环境已经激活,但 PATH 顺序不对,可能你系统的 Python 路径排在 conda 环境前面。Windows 上尤其常见,因为系统里可能有 Python 的“应用别名”或者旧 Path 残留。

如果$CONDA_PREFIX是空的,说明activate根本没生效,多半是 conda 没有完成 shell 初始化。执行conda init bash(或 zsh、fish、PowerShell 对应版本),然后重开一个终端。有时候你手动把conda命令加入了 PATH,但没跑过conda init,activate 就只是“看起来执行了”,实际环境变量没改。

最笨但有效的验证方式是:

which -a python

系统会列出所有能找到的 python 路径。如果envs/py37/bin/python排在/usr/bin/python后面,临时修一下:

export PATH="$CONDA_PREFIX/bin:$PATH"

但要根治,还是在同一个终端里只激活一个环境,别一会儿 base 一会儿 py37 来回切。我见过一个案例:连续激活两个环境,PATH 里出现了两个 envs 目录,顺序错乱,最后 python 命令指向了旧的那个。

5. 让 py3.7 与新版 conda 长期共存的姿势

5.1 保持 base 环境干净,别让旧版本拖垮 conda

经历了上面这些折腾之后,我有一条非常坚定的建议:base 环境永远不要直接降级到 py3.7。base 环境是 conda 自己的运行环境,你把它的 python 降到 3.7,连带着把所有 conda 依赖都降一遍,之后任何conda update都可能冲突,最后变成 conda 命令都起不来。

正确的姿势是:base 保持新版,比如 3.11 或 3.12,py3.7 作为独立环境存在。新版 conda 加旧版环境这种组合非常稳定,只要你不去更新 py3.7 环境里那些已经 EOL 的包,它几乎不会自己崩溃。万一真把某个 py3.7 环境搞乱了,也不要试图在里面修复,最快的办法是删除重建:

conda env remove -n py37 conda create -n py37 python=3.7

这套“推倒重来”的打法,比任何修复手段都省时间,这也是 conda 环境隔离最大的价值所在。

5.2 pip 与 conda 的边界要分清楚

在 py3.7 环境里装包,最容易出问题的就是把 pip 装的包和 conda 装的包混在一起。conda 管理的包放在pkgs目录下,pip 管理的包放在site-packages里,两边各有各的元数据,互相不知道对方存在。

我给自己定了四条规矩,写在这里供你参考:

  1. numpy、scipy、pandas 这类大件优先用 conda 装,因为 conda 能保证二进制依赖匹配。
  2. conda 里没有的包再用 pip,而且只装到当前环境,千万别加--user,否则会跨环境污染。
  3. 在 py3.7 环境里不要随便升级全局 pip,除非你明确知道当前 pip 版本和 Python 3.7 的兼容关系。
  4. 如果要从 py3.7 迁移到 3.8,不要先卸载旧环境,直接conda install python=3.8,让 conda 重算所有依赖,成功率远高于手动逐个装。

这里也提醒一点:py3.7 环境里的 numpy 等二进制包,在 conda-forge 目前还能下载,但defaults里可能已经逐步下架。想长期固定,创建环境时最好把 channel 锁住:

conda create -n py37 -c conda-forge --override-channels python=3.7

--override-channels表示只从 conda-forge 拉包,不掺入其他源。环境建成之后,以后升级也尽量不要切换源,否则依赖会重新解析,可能导致老版本组合失效。

5.3 安全与维护:py3.7 EOL 之后的务实选择

Python 3.7 在 2023 年 6 月 27 日正式 EOL,之后官方不再发布安全修复。conda-forge 对 py3.7 包的维护也进入末端,新包基本只提供 py3.8+ 版本。这对“让 conda 支持 py3.7”的人来说是个绕不开的现实:你能装上 py3.7 环境,但新依赖可能装不上。

我的做法是分情况处理。如果只是跑一个几个月后就要下线的小脚本,py3.7 环境完全够用,不需要焦虑。但如果这是一个维护期很长的服务,最好尽早留一条迁移路径。迁移时有个小技巧:在 py3.7 环境里先用conda env export导出环境文件,然后手动把里面的python=3.7改成python=3.8或python=3.10,再新建环境。这样大部分依赖能自动捡回来,不需要一个个去查“这个包最新版本支持哪个 Python”。

实际接触过这么多 conda 环境之后,我的体会是:新版 conda 创建的 py3.7 环境,性能上并不比当年在 py3.7 专用 Miniconda 里跑得差,真正的差别在维护预期——你得接受它是一个逐渐变老的环境。与其纠结“conda 到底支不支持 py3.7”,不如把这套环境隔离的方法用熟:什么时候该新建环境、什么时候该导出、什么时候该下决心迁移。掌握好这些边界,你才算真正拿捏住了 conda 的环境管理能力。

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

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

立即咨询