ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

cmd下Python虚拟环境配置:venv/conda/uv选型与激活原理

cmd下Python虚拟环境配置:venv/conda/uv选型与激活原理 打开cmd敲一行命令一个干净的Python环境就建起来了——这话听起来轻巧真正在生产机上折腾过的人都清楚中间隔着一堆具体问题python.exe到底装在哪、py启动器认不认、激活脚本被系统策略拦住、多版本解释器互相抢PATH、换台没网的机器还得把整套依赖搬过去。cmd下配置虚拟环境这件事看起来是个小操作实际上考验的是你对Windows进程环境变量、路径搜索顺序和包管理链条的理解程度。这篇内容不谈空泛概念就把从零配一套虚拟环境的完整链路摊开为什么要在cmd里做这件事而不是图形界面点两下、四种主流方案各自适合什么场景、创建到销毁的每一步背后发生了什么、以及那些只有亲手敲过才会撞上的报错。刚开始写Python的朋友能照着抄作业被全局装包搞乱过系统环境的老手也能在里面找到几个值得存档的细节。1. 在cmd里折腾虚拟环境到底图什么1.1 全局装包的代价我交过一次学费刚上手Python那两年我所有的包都是直接pip install到系统解释器里。前半年没感觉直到同时维护两个项目一个依赖某框架的1.x版本另一个必须用2.x的新API。装1.x的时候把2.x降级了另一个项目当场起不来。这种冲突在Windows上尤其难受因为Python默认装到C:\Users\你的用户名\AppData\Local\Programs\Python\Python3xx所有项目共用同一份site-packages目录谁先装谁说话算数。虚拟环境解决的正是这个隔离问题。它的本质非常朴素给每个项目复制一套独立的site-packages目录再在激活的时候把解释器和这个目录绑定起来。我在cmd里配环境图的是三个实在的东西。透明。图形化工具点完按钮环境建在哪个路径、用哪个Python版本、装了什么包你得再点好几层才看得见cmd里一行命令执行完当前目录多了个.venv文件夹清清楚楚。可脚本化。批处理文件、CI流水线、远程部署脚本最终落地的形态都是命令行。早点习惯在cmd里操作迁移到自动化环节时几乎没有学习成本。可复现。命令本身就是文档。我把创建环境的命令写进项目根目录的setup.bat换电脑或者交给同事双击一下就还原了。1.2 激活虚拟环境真正发生了什么很多人把激活理解成一个神秘的开关其实它做的事用一句话就能概括把虚拟环境的Scripts目录临时插到当前cmd会话的PATH最前面。你可以自己验证建好环境后执行set PATH能看到.venv\Scripts出现在最左侧同时多了一个VIRTUAL_ENV变量指向环境根目录。:: 激活前看看 python 指向谁 where python call .venv\Scripts\activate.bat :: 激活后再看 where python echo %VIRTUAL_ENV%看明白这个机制几个常见困惑就自动解开了。为什么关了cmd窗口环境就没了。因为PATH的修改只存在于当前这个cmd进程的内存里进程一退修改全部蒸发下次开窗口又是系统默认的那份PATH。这不是bug是设计如此。为什么必须有deactivate。activate.bat在动手之前会先把原始PATH存进_OLD_VIRTUAL_PATH这个变量deactivate就是把它读回来覆盖掉。如果你直接手动改PATH或者在一个cmd里反复激活多个环境而不退出PATH会越叠越长最后where python列出一长串谁也说不清当前用的是哪个。为什么子进程继承不了。激活是进程级的你在A窗口激活了另开一个B窗口不受影响。这点在跑批处理脚本时特别重要后面第6节会细说。提示判断当前是否处于虚拟环境中最可靠的命令是python -c import sys; print(sys.prefix ! sys.base_prefix)。输出True说明在虚拟环境里False说明在用系统解释器。比看命令行前面的括号提示靠谱得多因为那个括号只是activate.bat改了PROMPT变量显示的。1.3 cmd、PowerShell、Windows Terminal 该怎么选Windows上现在至少有三套终端可选虚拟环境的激活脚本也是三套不同的文件这是新手最容易懵的地方。用venv创建完环境.venv\Scripts目录里会同时躺着activate.bat、Activate.ps1和activate给Git Bash之类的类Unix shell用。终端环境使用的激活脚本典型拦路虎cmd.exeactivate.bat基本没有最省心PowerShellActivate.ps1默认执行策略限制脚本运行Git Bashactivate路径反斜杠与正斜杠的转换Windows Terminal取决于打开的profile需要确认当前开的是哪种shell我个人的建议是日常开发用Windows Terminal但把它的默认profile设成Command Prompt。Windows Terminal的标签页、分屏、字体渲染体验都比老的cmd窗口好太多而命令行解析层又保留了cmd的原生行为不用操心执行策略。如果非要留在PowerShell那就先执行一次策略调整Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUserRemoteSigned的含义是本地写的脚本可以直接跑从网上下载的脚本需要数字签名。-Scope CurrentUser保证只影响你自己这个账户不去动机器级别的策略这是最小权限原则。改完策略后如果不生效在PowerShell里执行.venv\Scripts\Activate.ps1时前面必须带.\这是PowerShell的安全设计不允许直接从当前目录执行命令。2. 四种主流方案摆在cmd里怎么选2.1 venv、virtualenv、conda、uv 各自的位置现在能建Python虚拟环境的工具至少四个各自的历史包袱和适用场景差别很大。选错了不会出大乱子但会在某些环节反复硌脚。venv是Python 3.3之后内置的标准库模块不需要额外安装随Python版本一起走。它的定位就是够用的最小实现创建速度快生成的环境干净依赖pip装包。缺点是它只管Python本身如果你的项目还需要某个特定版本的编译工具链或者非Python的运行时venv帮不上忙。virtualenv是venv出现之前的第三方方案现在依然在维护而且比venv多了几个实用特性可以创建比当前Python版本更老的虚拟环境、创建速度更快、支持--copies参数把解释器真复制一份而不是做软链接。如果你在用Python 3.6以下的老版本某些工业软件绑定的运行时就是这样venv不可用只能上virtualenv。conda以及Anaconda、Miniconda走的是另一条路线它不只是Python包管理器而是一个通用的二进制包与环境管理器。数据科学、机器学习场景里大量依赖需要预编译好的BLAS、CUDA相关库这些东西通过pip装极其容易失败conda的预编译二进制包能省掉大量编译时间。代价是环境体积大、conda activate需要额外初始化、跨平台复现性不如纯pip方案稳定。uv是这两年的新变量用Rust写的把包解析和下载做得极快。它同时提供两种用法作为venv的替代品创建环境uv venv以及作为pip的替代品装包uv pip install。它还自带uv sync基于pyproject.toml和uv.lock做锁定式复现。速度优势在依赖树复杂的项目上非常明显我实测过一个有180多个依赖的项目uv装完大概十几秒pip要三分钟以上。2.2 一张表把选型问题说清楚方案是否需要额外安装创建速度环境体积最适合的场景venv否内置中等最小纯Python项目、Web后端、脚本工具virtualenv需要pip装快小老版本Python、需要解释器实体复制conda需要装Miniconda/Anaconda慢大数据科学、需要非Python依赖、CUDA环境uv需要单独安装二进制极快小依赖多、重建频繁、追求复现速度我的实际工作流是这样的普通的后端服务和工具脚本一律用venv需要跑深度学习实验的时候另开conda环境碰到依赖装得慢或者频繁重建的项目用uv。这三者不冲突同一台机器上完全可以共存因为它们的激活机制都是改PATH只是各自的命令前缀不一样。还有一个实际考量是团队协作。如果团队里已经统一用了conda你一个人切uv会让environment.yml和requirements.txt两套文件并存交接时容易乱。选型这件事技术优劣只占一半另一半是团队共识。2.3 版本管理工具链该放在哪一层有个概念容易混淆虚拟环境管理和Python版本管理是两件不同的事。venv解决的是这个项目用哪些包但它管不了这个项目用哪个Python大版本。你在Python 3.11下建的venv里面就是3.11的解释器。版本管理我推荐用Windows自带的py启动器安装Python时勾选py launcher就会装它比手动改PATH优雅得多:: 列出机器上所有已注册的 Python 版本 py -0 :: 用指定的 3.10 建虚拟环境 py -3.10 -m venv .venv :: 查看当前默认版本 py --versionpy -0的输出会列出每个版本及其安装路径前面带*的是默认版本。这个列表是从注册表读的比where python靠谱得多——where python只能看到PATH里排在前面的那一个注册表里装了多少个它一个都看不见。搞清楚机器上到底有几个Python是排查为什么我装的包不见了这类问题的第一步。3. venv从创建到销毁的完整命令链路3.1 动手之前先做三项检查直接开敲命令之前有三件事值得花两分钟确认我在不同的机器上至少被这三项各坑过一次。第一项确认python指向的是不是你想要的解释器。执行where python python -c import sys; print(sys.executable, sys.version)第一行列出PATH里所有叫python的可执行文件第二行打印当前实际生效的解释器路径和版本号。如果第一行输出好几条说明PATH里有多个Python谁排前面谁生效。这种情况下我通常会临时把不需要的从PATH里移除或者干脆全程用py -3.11 -m venv这种显式指定版本的方式。第二项确认pip本身的归属。执行pip -V输出格式是pip 24.0 from ... (python 3.11)。如果这里的python版本和你上一步看到的对不上说明pip和python来自不同的安装后面装包一定会装到错误的目录里去。这是Windows上非常典型的问题因为pip的脚本入口是写在Scripts目录下的pip.exe它内部硬编码了python路径。第三项确认当前目录。虚拟环境默认建在当前工作目录下如果建错地方目录结构会变得很难看而且路径越长越容易碰到长度限制。用cd /d D:\projects\myapp这种带/d的写法可以跨盘符切换不带/d的话从C盘切到D盘是切不过去的这是cmd和Linux shell的一个显著区别。注意项目路径里尽量避免中文、空格和符号。venv本身对中文路径兼容性还行但很多第三方工具的脚本里对路径做了字符串拼接遇到空格会截断遇到中文可能触发编码错误。我在一个路径含中文的项目上遇到过pip install反复失败换成纯英文路径后立刻正常排查了两个小时才发现问题所在。3.2 创建、激活、退出、删除四步走确认完环境正式开工。四步操作每步我都把命令和它背后做了什么一起说清楚。第一步创建。cd /d D:\projects\myapp python -m venv .venv为什么用python -m venv而不是直接venv因为venv这个模块名不是可执行文件必须通过-m参数让Python把它当模块执行。python -m venv还有个好处它能保证用的是你刚确认过的那个python解释器避免PATH里存在一个独立的venv.exe把你带偏。创建完成后目录里会出现这样的结构.venv/ ├── Include/ ├── Lib/ │ └── site-packages/ - 新装的包都落在这里 ├── Scripts/ │ ├── activate.bat │ ├── Activate.ps1 │ ├── deactivate.bat │ ├── python.exe │ ── pip.exe ── pyvenv.cfg - 记录这个环境的信息pyvenv.cfg这个文件值得单独看一眼它的内容大概长这样home C:\Program Files\Python311 include-system-site-packages false version 3.11.9home指向创建这个环境时用的原始Python安装目录。Python启动时会先找自己所在目录有没有pyvenv.cfg有的话就认定自己运行在虚拟环境里然后去读home找到标准库的位置。这就是虚拟环境轻量的原因——它不复制整个标准库只复制了Scripts下的几个入口程序和空目录标准库还是共用系统那份。第二步激活。call .venv\Scripts\activate.bat这里call关键字不能省。如果直接写.venv\Scripts\activate.batcmd会把这个bat当独立进程执行它修改的PATH在子进程里执行完就没了你的当前会话什么都没变。加上call表示在当前进程上下文里执行这个脚本修改才能留在当前会话里。激活成功的标志是命令行提示符前面多出(.venv)。这个前缀是activate.bat改了PROMPT环境变量实现的纯装饰作用不参与任何逻辑判断所以别用它来判断当前环境状态。第三步退出。deactivate不需要加任何参数也不需要带路径因为activate.bat已经把deactivate.bat所在目录放进了PATH。执行后提示符前缀消失where python重新指向系统解释器。第四步删除。deactivate rmdir /s /q .venvrmdir /s /q是递归删除且不询问。执行前必须确保已经退出了环境否则Scripts\python.exe还被占用Windows会报文件正在被另一个进程使用删不掉。如果实在退不出来用tasklist | findstr python找到占用进程的PIDtaskkill /PID 那个数字 /F强杀。3.3 激活失败的三类报错逐个拆报错一activate.bat 不是内部或外部命令。这个报错百分之九十是路径写错了。.venv\Scripts\activate.bat是相对路径前提是你的工作目录就是项目根目录。用cd确认一下或者干脆写绝对路径。还有一种情况是环境根本就没建成功去检查.venv目录是不是空的如果Scripts目录都不存在说明创建那一步就失败了回去看创建时的报错信息。报错二PowerShell下提示无法加载文件 Activate.ps1因为在此系统上禁止运行脚本。这是执行策略的问题前面1.3节给过解决方案。补充一个细节有些人改了策略还是不行原因是用管理员身份开了PowerShell但改的是LocalMachine作用域而普通用户进程读的是CurrentUser作用域。用Get-ExecutionPolicy -List可以列出所有作用域的当前设置一目了然。报错三激活了但pip install还是装到了系统目录。验证方法是在激活状态下执行python -c import sys; print(sys.prefix) pip -Vsys.prefix应该指向.venv的绝对路径pip -V后面的括号里也应该出现.venv字样。如果对不上八成是这个环境在创建时用了--system-site-packages参数允许访问系统包或者环境已经损坏——最直接的处理办法是删掉重建虚拟环境的价值就在于随时可以抛弃不值得花时间修。4. 依赖锁定与环境搬迁的实操细节4.1 requirements.txt 的生成方式有讲究环境建好、包装完下一步是把它记录下来让别人或者未来的自己能还原。pip freeze requirements.txt是最常见的做法但它有几个必须知道的副作用。pip freeze输出的是当前环境里所有已安装包的精确版本包括你根本没直接装过的间接依赖。一个只写了flask的项目freeze出来可能有十几行因为flask自己会拖一堆依赖进来。这在部署时是好事版本完全锁定不会因为上游发新版导致行为变化但在开发时是坏事你没法从这份文件里看出哪些是你真正需要的。我的做法是维护两份文件文件名内容用途requirements.in手写的直接依赖只写包名和宽松版本开发时维护人看得懂requirements.txtfreeze出来的完整锁定列表部署和复现时使用两者之间的转换可以用pip-toolspip install pip-tools pip-compile requirements.in -o requirements.txt pip-sync requirements.txtpip-compile会把.in里写的宽松约束解析成完整锁定列表pip-sync则会把当前环境严格同步成文件描述的样子——注意是同步多装的包会被卸掉这比pip install -r的增量安装更彻底。4.2 没网的机器上怎么把环境搬过去这是实际工作中绕不开的场景开发机在办公室目标机在车间或者内网机房中间只能用U盘拷。思路是把包文件先下载下来再离线安装。第一步在联网机器上执行mkdir offline_pkgs pip download -r requirements.txt -d offline_pkgs ^ --platform win_amd64 ^ --python-version 311 ^ --only-binary:all:三个关键参数必须说清楚。--platform win_amd64指定目标平台因为pip download默认下载的文件是匹配当前平台的如果开发机是ARM架构而目标机是x86不指定就会下错。--python-version 311指定Python版本格式是不带点的三位数写3.11会报错。--only-binary:all:强制只下载预编译的wheel文件跳过需要本地编译的源码包——离线机上大概率没有编译器源码包下过去装不了。第二步把整个offline_pkgs目录拷到目标机在目标机建好虚拟环境后执行pip install --no-index --find-linksoffline_pkgs -r requirements.txt--no-index表示完全不访问在线索引--find-links告诉pip去本地目录找包。这两个参数一起用能保证pip不去联网即使目标机其实有网也会走本地文件避免装到和预期不一样的版本。提示pip download遇到有平台专属wheel的包比如numpy、pandas这种带C扩展的下载下来的文件名里会带cp311、win_amd64这样的标签。如果目标机的Python版本或者位数和下载时不匹配pip会直接跳过这个wheel去找源码包然后失败。所以下载前务必确认目标机的Python具体版本号3.11.9和3.11.5在wheel标签上是一样的但3.11和3.12不通用。4.3 虚拟环境能不能直接复制目录不能这是很多人想当然的地方。pyvenv.cfg里的home字段记录了原始Python的绝对路径Scripts下的activate.bat、pip.exe这些脚本里也硬编码了环境创建时的路径。你把.venv整个目录拷到另一台机器上哪怕Python版本完全一致激活后也会出现各种诡异问题——pip报找不到模块或者装包装到了原来那台机器的路径下去。如果确实需要复制环境正规做法是用requirements.txt在目标机上重建然后重新安装。真要复制目录一个相对可行的变通是python -m venv .venv_new新建一个干净环境然后把旧环境Lib\site-packages下的目录整体拷到新环境的对应位置。这样做能绕过路径硬编码的问题因为新环境的路径信息是重新生成的。但这样做的前提是两台机器的Python小版本完全一致否则带C扩展的包照样会崩。顺便说一个相关的参数python -m venv --copies .venv。默认情况下venv在某些配置下会用符号链接指向原始Python解释器加上--copies会实体复制一份python.exe。在需要把环境打包分发的场景下--copies能减少对原始安装的依赖代价是占用空间大一些。5. conda和uv在cmd里的两个特殊脾气5.1 conda activate 为什么在cmd里没反应如果你装了Miniconda兴冲冲在cmd里敲conda activate myenv大概率得到一句CommandNotFoundError提示你运行conda init。这不是conda坏了而是它的激活机制和venv根本不同。venv的激活是改PATH而conda的activate在较新版本里是一个shell函数必须在shell启动时就被注入到环境里才能用。conda init cmd.exe做的就是这个注入工作它会在Windows注册表的HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun这个键里写一条命令让每次cmd启动时自动执行conda的初始化脚本。:: 在 Anaconda Prompt 里执行不是普通 cmd conda init cmd.exe执行完关掉所有cmd窗口重新开一个conda activate就能用了。但这件事有个副作用值得提前知道所有cmd窗口的启动都会变慢因为每次都要跑一遍初始化脚本实测冷启动会多出几百毫秒到一秒。对于经常开cmd跑小命令的人来说这个延迟挺烦的。我的处理方式是平时不init只在需要用conda的时候打开Anaconda Prompt。如果确实想在cmd里用就接受这个启动开销。还有个折中办法是写一个专门的bat文件里面显式调用conda的激活脚本echo off call %USERPROFILE%\miniconda3\Scripts\activate.bat myenv cmd /k这样只有这个特定的快捷方式会走conda初始化普通cmd窗口不受影响。注意这里用的还是call理由和venv那边一样。5.2 uv 的两层命令别搞混uv的命令体系分两层刚接触的时候容易懵。第一层是环境层对应uv venv第二层是包层对应uv pip。:: 创建环境默认就建在 .venv不需要额外命名 uv venv :: 指定 Python 版本 uv venv --python 3.12 :: 在当前环境里装包命令形态和 pip 几乎一致 uv pip install flask uv pip install -r requirements.txt :: 从 requirements.txt 严格同步会卸载多余的包 uv pip sync requirements.txtuv pip这一组命令是设计成pip的直接替代品的参数名基本兼容迁移成本很低。真正体现uv设计思路的是上层的那套uv init/uv add/uv sync/uv run。用uv init初始化项目会生成pyproject.tomluv add flask会把依赖写进这个文件并更新uv.lockuv sync按lock文件精确还原环境uv run python main.py则会在执行前自动确认环境是最新的。uv init myproject cd myproject uv add requests uv run python main.py这套流程的好处是不需要手动管理激活状态uv run自己会处理。对于写一次性脚本或者跑工具类命令的场景比反复激活要顺手。我踩过的一个坑是权限问题。uv在Windows上会优先使用硬链接来构建环境这要求存放缓存的盘和项目所在的盘是同一个卷。如果项目在D盘而uv的缓存在C盘硬链接创建失败它会自动回退到复制文件速度会慢下来但不报错。想避免这个问题可以用UV_LINK_MODEcopy显式指定复制模式或者把UV_CACHE_DIR环境变量指到项目所在盘。6. 让cmd和编辑器、脚本配合起来6.1 VSCode 识别环境的正确姿势VSCode选解释器的入口是CtrlShiftP打开命令面板搜Python: Select Interpreter然后选.venv\Scripts\python.exe。选完之后VSCode会记住这个选择写进.vscode\settings.json的python.defaultInterpreterPath字段这样团队成员拉到代码后自动就能用上。有个设置值得改一下就是终端自动激活{ python.terminal.activateEnvironment: true, terminal.integrated.defaultProfile.windows: Command Prompt }第一项控制的是VSCode打开集成终端时是否自动激活当前项目的虚拟环境。默认是开的但它在PowerShell下会去执行Activate.ps1碰到执行策略限制就静默失败终端看起来正常但实际用的是系统Python。第二项把默认终端改成Command Prompt走activate.bat这条路绕开策略问题是我试过的省心方案。顺带一提VSCode的Python扩展在检测环境时有自己的逻辑它会扫描工作区下所有叫.venv、venv、env的目录。这也是我建议把环境目录统一命名为.venv的原因——名字对了编辑器不用配置就能自动发现。6.2 一个bat脚本把环境准备全包掉项目交给别人时最省事的做法是配一个双击就能跑的批处理。下面这个脚本我在好几个项目里复用逻辑是先判断环境存不存在不存在就建好并装依赖存在就直接进入。echo off chcp 65001 nul cd /d %~dp0 if not exist .venv\Scripts\activate.bat ( echo 首次运行正在创建虚拟环境... py -3.11 -m venv .venv call .venv\Scripts\activate.bat python -m pip install --upgrade pip pip install -r requirements.txt ) else ( call .venv\Scripts\activate.bat ) echo 环境已就绪%VIRTUAL_ENV% cmd /k逐行解释几个关键点。chcp 65001把代码页切到UTF-8避免中文提示信息变乱码。cd /d %~dp0切换到脚本自身所在目录%~dp0是批处理的特殊变量表示脚本的完整路径这样不管从哪个目录双击都能正确定位项目根目录。cmd /k在脚本执行完后保留一个交互式窗口/k表示执行完命令不关闭这样用户能立刻开始敲命令。这里有个必须强调的细节所有对activate.bat的调用都加了call。不加的话activate.bat会在子进程里执行线程结束后环境变量丢失后面那行pip install就装到系统Python里去了——这个错误非常隐蔽脚本看起来跑完了实际上什么都没装到正确位置。6.3 路径、编码、占用这三个老对手聊几个在cmd下配环境时反复出现、每次都要重新想一遍的问题。路径里的空格。C:\Program Files\Python311这个路径里带空格在bat脚本里引用必须加引号C:\Program Files\Python311\python.exe。不加引号的话cmd会把它当成两个参数处理报系统找不到指定的路径。venv创建时会自动处理这个问题它在pyvenv.cfg里记录的路径是加了引号的但如果自己写脚本调用解释器这一步不能忘。输出编码。cmd默认的代码页在简体中文系统上是936GBK。如果Python脚本往stdout打印UTF-8字符或者读一个UTF-8的配置文件很容易碰到UnicodeEncodeError。临时解决办法是在命令前加chcp 65001或者设置环境变量PYTHONIOENCODINGutf-8。后者更精准只影响Python进程的输入输出编码不动整个终端。文件占用。这是删除环境时最常见的障碍。除了前面提到的Python进程还有一些隐形的占用者Jupyter内核、调试器进程、某些编辑器的语言服务器。排查命令tasklist | findstr /i python jupyter找到可疑进程后用taskkill /PID xxx /F处理。如果还是删不掉用资源监视器resmon的CPU标签页下方的关联的句柄搜索框输入.venv会直接列出所有持有这个目录句柄的进程。这个技巧比盲目杀进程高效得多我在处理环境删不掉但又看不出谁在用的问题时基本都靠它。环境变量污染。有时候你在一个cmd里激活过环境又手动改过PATH然后各种奇怪的问题开始出现。最干净的排查手段是开一个全新的cmd窗口执行set PATH和预期做对比。实在乱得看不清把当前窗口关掉重开就行——这也是cmd相比PowerShell的一个小优势环境变量的修改天然是会话级的关窗即复原。最后分享一个我在长期使用中固定下来的习惯在项目根目录放一个env_info.txt里面记录创建环境时用的Python版本、创建日期、以及关键依赖的版本号。看似多余但当你半年后回头维护一个老项目想确认当时这个环境是不是用3.10建的时翻这个文件比翻聊天记录快得多。虚拟环境本身是易耗品随时可以删掉重建但它对应的那组版本信息是有价值的值得单独留一份。
返回列表