
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 GB1500 预装包是是新手、数据科学、教学环境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, /DD:\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 # 初始化 shellzsh 是 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 的配置文件叫.condarcWindows 上在C:\Users\你的用户名\.condarcLinux/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.confWindows 写%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_dirsconda config --add envs_dirs D:\conda_envs conda config --add pkgs_dirs D:\conda_pkgs3. 虚拟环境配置从创建到导入导出的完整链路3.1 创建环境版本、命名与位置的取舍创建环境最常见的命令是这条conda create -n proj311 python3.11 -y参数背后的逻辑值得说清楚。-n后面跟的是环境名这个名字会被用来做目录名所以别用中文、别用空格、别用特殊符号。python3.11是版本约束conda 会去通道里找一个满足条件的 Python 版本如果你写python3它会给你装 3.x 里最新的一个写python3.11.5则会精确到小版本。我的习惯是锁到次版本号比如3.11这样能在复现性和安全性补丁之间取个平衡。命名我建议带上项目特征和 Python 版本比如web311、cv310、nlp312。环境多了以后conda env list一屏看下来一眼能分清哪个是哪个比env1、env2、test这种命名强太多。-y是跳过交互确认写脚本的时候必加。如果你不想把环境放在默认的envs目录下可以用-p指定绝对路径conda create -p D:\projects\myproj\env python3.11 -y这种项目内环境的好处是跟项目目录一起管理删项目的时候顺手带走环境不会在envs目录里留下一堆孤儿环境。坏处是硬链接可能失效跨盘以及conda activate的时候必须给完整路径不能只给名字。取舍看你的项目管理习惯我个人的做法是长期维护的通用环境用-n一次性实验、临时验证用-p放项目目录里。创建时还可以一并装包减少来回操作conda create -n proj311 python3.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: - python3.11.5h5b6c2f3_0 - numpy1.24.3py311h1f0d5a7_0 - pip: - torch2.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: - python3.11 - numpy - pandas - pip - pip: - torch2.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 安装路径的时候。最直接的方式是用命令面板CtrlShiftPmacOS 是CmdShiftP输入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设为 trueVS 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.shCommandNotFoundError: Your shell has not been properly configured同上只管了 activate 场景执行conda initPowerShell 还要放开执行策略Solving environment: failed/ 卡住不动经典求解器性能问题、通道冲突设置solver: libmamba、channel_priority: flexible减少混用通道PackagesNotFoundError包名拼错、通道没加检查拼写conda config --add channels conda-forge装了包但 import 失败解释器/内核不是同一个环境打印sys.executable注册 Jupyter 内核ImportError: DLL load failedWindows缺少 Microsoft Visual C 运行库安装对应版本的 VC Redistributable装包速度极慢或超时默认源、pip timeout 太短换源、timeout120、加大重试次数环境占用磁盘异常大硬链接失效导致复制、缓存未清统一envs_dirs与pkgs_dirs盘符conda clean -a导入 yml 失败含 build string 或 prefix、跨平台改用conda env export --from-history--prune后依赖缺失清单不完整用完整清单重建或补全 yml 后重新 update5.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 pipWindows 用where python确认两个路径都指向目标环境。第三环境变量在 conda 环境内外不一致。激活环境会重置部分环境变量尤其是PYTHONPATH和LD_LIBRARY_PATH。如果你在~/.bashrc里设了PYTHONPATHconda 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 或者笔记里。环境多了以后你迟早会遇到这个模块昨天还能跑今天怎么不行了的情况有一份环境基线记录回溯问题时能省掉大量猜测。环境配置这件事本身不难难的是坚持一套一致的规则不要每次凭感觉来那样环境越攒越多最后就是一团谁也理不清的乱麻。