
1. 为什么Python 2必须退场以及卸载前必须想清楚的三件事先聊点实际的。2020年1月1日Python 2官方停止维护那天我手头还有三台服务器跑着Python 2.7写的内部工具有数据清洗脚本有自动化报表还有一个定时抓取业务系统数据的爬虫。当时觉得反正还能跑不升就不升吧结果后来装一个第三方库时发现版本不兼容才被迫开始大规模迁移。真正动手后才发现Python 2退场不是换个解释器这么简单它牵扯到语法差异、依赖库版本、系统底层工具链一不小心就把环境搞崩。如果你现在也是电脑里有Python 2残留、想升级到Python 3我建议先别急着下载安装包把下面三件事想清楚。第一确认系统是否默认依赖Python 2。特别是Linux/macOS系统很多系统工具比如Linux里的yum、某些发行版里的包管理脚本底层还是调用Python 2的。你要是手一抖把Python 2直接删了系统工具可能当场罢工。这不是危言耸听我见过有人把/usr/bin/python指向Python 3之后yum直接报错最后只能靠救援模式把软链接改回来。所以下面的步骤里我会专门说怎么安全处理这个系统依赖问题。第二分清你的Python 2是自己装的还是系统自带的。Windows上通常是自己装的卸载相对干净Linux上则要区分是yum install python2装的还是系统里天生就有的。两者卸载方式完全不同混着来很容易留下残缺文件下次装Python 3时路径冲突烦死你。第三你的旧项目里有没有必须用Python 2才能跑的代码。Python 2和Python 3在语法上有不少差异最经典的是print从语句变成了函数/除法的行为也变了字符串编码更是重灾区。如果你有旧代码依赖Python 2的Unicode处理方式强行切到Python 3会出一堆乱码问题。最稳妥的做法是先把Python 3下载安装好让新旧版本共存一段时间等确认脚本全部跑通再考虑卸载Python 2。这篇文章我就把Python 3下载安装 Python 2卸载这件事拆开揉碎分别讲Windows、Linux和macOS三种环境下的完整流程每步都告诉你为什么要这么干以及最容易踩的坑在哪。内容是我近几年在真实服务器和个人电脑上反复操作的总结不是那种只能看不能用的教程。2. Python 3各平台下载安装的完整操作与路径管理2.1 Windows官网下载安装包勾选Add to PATH是关键Windows装Python 3其实是最省心的但省心不等于没有坑。下面是标准流程。先去Python官网python.org的Downloads页面挑一个你需要的版本。别一上来就追最新版很多第三方库的兼容性往往滞后。我个人习惯用最新稳定版往前退一个小版本的版本比如最新是3.12我就装3.11库兼容性最稳。下载时注意区分32位还是64位现在新电脑基本都64位直接选Windows installer (64-bit)。安装时有个复选框叫Add Python to PATH一定要勾选。这是新手最容易忽略的不勾的话装完后在cmd里敲python会提示找不到命令。勾选后安装程序会在系统环境变量PATH里自动加上Python目录和Scripts目录省得你手动配置。安装方式我推荐选Customize installation虽然Install Now也能用但自定义安装可以让你确定安装路径和可选组件。这里有个细节安装路径建议改成不含空格的目录比如D:\Python311。默认的C:\Users\用户名\AppData\Local\Programs\Python\Python311包含空格和中文用户名少数老旧的第三方库在import时会因为路径问题报错我确实遇到过。组件配置里如果你是做爬虫或数据分析的记得勾选pip和py launcher前者是包管理工具后者是帮你管理电脑上多个Python版本的工具。装完打开cmd输入python --version如果显示Python 3.x.x说明装好了。这时候可以顺手验证下pippip --version2.2 Linux主流发行版的Python 3安装方式和路径冲突Linux的情况比Windows复杂因为很多发行版自带Python 3。先看系统里有没有python3 --version如果显示Python 3.x那就不用装了直接用。但如果你想要一个独立的新版本比如系统自带3.6你想用3.11有两个主流方式。方式一用系统包管理器装。Ubuntu/Debian用aptCentOS/RHEL用yum或dnf。以Ubuntu安装Python 3.11为例sudo apt update sudo apt install python3.11装完后验证下python3.11 --version。这种方式的好处是库和路径都被系统统一管理不太容易出乱子。缺点是版本一般比官网慢一点不是最新。方式二从源码编译安装。想要最新版或者想自定义安装路径就自己编译。这个流程适合有Linux基础的人新手建议先用系统包管理器。# 下载源码包 wget https://www.python.org/ftp/python/3.11.0/Python-3.11.0.tgz # 解压 tar -xzvf Python-3.11.0.tgz cd Python-3.11.0 # 配置安装路径建议独立目录避免和系统Python冲突 ./configure --prefix/usr/local/python311 --enable-optimizations # 编译安装 make -j$(nproc) sudo make install编译时那两个参数说一下。--prefix指定安装目录我刻意让Python 3.11装在/usr/local/python311这样和系统自带的Python 3完全隔离不会出现明明升级了程序却还在跑旧版本的诡异情况。--enable-optimizations会做性能调优编译时间会长一些但运行时速度更好。装完后设置环境变量# 编辑用户级环境变量文件 echo export PATH/usr/local/python311/bin:$PATH ~/.bashrc source ~/.bashrc这样输入python3就会优先用新版本了。注意最好不要去改/usr/bin/python3这个软链接因为系统很多服务脚本在调用它一改就会引发连锁反应。2.3 macOSpyenv管理多版本比直接装更省心macOS上系统自带的Python 3其实是Apple为了让Xcode等工具正常运行而打包的不建议直接用它来做开发更不建议删掉系统Python。我的做法是装pyenv专门用来管理多个Python版本。首先确保装了Homebrew然后brew install pyenv之后在~/.zshrc里加入初始化配置eval $(pyenv init -)注意如果你用zsh配置文件是.zshrc如果还在用老的bash就是.bashrc或.bash_profile。改完记得source一下。然后用pyenv安装Python 3.11pyenv install 3.11.0安装过程中pyenv会自动编译同样需要等待。装好后设置全局版本pyenv global 3.11.0这时候再敲python --version就是Python 3.11了。pyenv的核心价值在于它会在PATH最前面插入一个shims目录让你的python命令动态指向当前项目或全局配置的版本不同项目用不同Python版本互不干扰。现状是很多依赖指定了Python版本的项目靠pyenv完美解决。macOS这条路我之所以推荐给大多数人是因为它从一开始就不需要操心删掉系统Python这个问题——你用pyenv系统Python就当它不存在好了各过各的。2.4 环境变量和python与python3命令的差异不管是哪个平台装完Python 3后都要搞清楚一个问题你终端里敲的到底是python还是python3Windows下如果你勾选了Add to PATH一般python和python3都能用。但在Linux和macOS上这俩命令可能指向完全不同的版本。很多新手就是在这一点上吃了亏明明python3已经是很新的版本了但脚本或命令行里用的是python跑的却是老掉牙的Py2或者一个奇怪的旧版本。想确认你到底用的哪个Python可以用下面这行命令它会打印出Python解释器的真实路径which python which python3Windows上用where python如果输出路径不一样说明你确实有两个Python在抢命令。最稳妥的做法是统一在脚本或命令里显式写python3并在虚拟环境里工作而不是依赖系统级python命令。说到虚拟环境这里必须插一句Python 3.3以上的venv就是隔离环境的标准工具强烈建议一上来就养成每个项目建一个venv的习惯。原因很简单——你全局环境里装了一堆库总会撞车的A库要numpy 1.xB库要numpy 2.x全局只可能有一个。venv把每个项目的依赖隔离在一个独立目录里再也不会出现这种冲突。创建venv的命令python3 -m venv myproject_env source myproject_env/bin/activate # mac/linux myproject_env\Scripts\activate # windows建好venv后pip安装的包都会装进这个环境的site-packages和系统其他Python完全隔离。我自己的所有项目都这么管理时间长了你就知道这个习惯有多值钱。3. Python 2卸载的完整流程与系统依赖风险排查3.1 先判断你的Python 2是系统依赖还是独立安装这一步绝对不能跳过我前面踩过坑这里必须说得极端清楚。先看系统里Python 2在哪里Windows上打开控制面板 - 程序和功能看有没有Python 2.x的条目。有的话说明是独立安装的后面直接用卸载程序就行。但Windows上也可能存在别人打包软件时代带进来的Python 2残留控制面板里可能看不到这种情况我在第3.3节会说怎么清理。Linux上先执行which python2 python2 --version如果which python2显示/usr/bin/python2那基本是系统自带的。别急着删先检查系统里哪些包依赖它。Linux检查依赖的命令rpm -qR python2 2/dev/null | head -20 # CentOS/RHEL apt-cache rdepends python2 2/dev/null | head -20 # Ubuntu/Debian或者直接用rpm -e模拟卸载看依赖rpm -e --test python2如果输出一大堆is needed by ...说明有系统工具依赖它强行删除很可能导致yum或apt崩溃。相对安全的办法是保留它不动只是把默认python指向Python 3然后让Python 2养老在系统里。反正它除了占点磁盘空间平时也不会主动出来惹事。macOS上系统自带的Python 2在旧版本macOSMojave及之前存在于/usr/bin/python。苹果官方和社区的主流建议都是不要手动删因为系统某些底层组件和脚本会调用它。真正想摆脱Python 2靠的是把/usr/local/bin或pyenv里新版本放到PATH前面让所有命令默认优先用Python 3。3.2 Windows环境中Python 2的标准卸载与残留清理如果你的Windows控制面板里明确看到Python 2.x操作就简单了。先去控制面板卸载。卸载完建议重启一下电脑让环境变量彻底刷新。检查环境变量PATH里还有没有Python 2的残留路径比如C:\Python27和C:\Python27\Scripts。有的话就删掉否则以后系统的where python可能会显示一个幽灵路径新装的Python 3反而排到后面去命令怎么敲都不对。这里我要多说一句令人头疼的事有些软件在安装时会把Python 2装到一个不显眼的位置不经过程序和功能入口而是直接写一个文件到系统里比如旧版Golden Software、某些测绘工具、十年前的内网办公系统等。它们的特征是控制面板里看不到Python 2但你在cmd里敲python却会弹出Python 2的交互界面。遇到这种情况我的处理方式是先用where python把实际路径找出来找到后手动审查这个目录里是哪家公司打包的Python。确认是第三方软件的私有Python后不要直接用文件夹删除因为软件下次启动可能报错。正确做法是先去该软件设置里找有没有自带Python选项并关闭或者重装该软件并选择不安装Python组件。如果实在找不到关联软件但你确定这个Python 2不是自己装的备份好相关目录后删除然后观察日常软件是否异常。注意这属于最后手段没事千万别轻易对未知来源的Python 2下手。3.3 Linux中的软链接替换法不真正卸载却让Python 2彻底退役很多人对卸载有执念认为系统里存在Python 2就是不干净。但从运维角度说有时候不卸载反而是最安全的方案。对于系统依赖Python 2的情况我强烈推荐替换优先路径的做法而不是物理删除。以CentOS 7为例系统自带的Python 2.7被yum和/usr/libexec/urlgrabber-ext-down依赖删掉之后yum直接废掉。我的做法是这样。第一步安装Python 3后创建自己的管理目录按第2.2节的方式装到/usr/local/python311这样Python 3已经在新路径下正常工作。第二步修改PATH变量让新Python 3排在最前echo export PATH/usr/local/python311/bin:$PATH /etc/profile.d/python311.sh source /etc/profile.d/python311.sh第三步把常用的python命令软链接指向Python 3sudo ln -s /usr/local/python311/bin/python3.11 /usr/local/bin/python sudo ln -s /usr/local/python311/bin/pip3.11 /usr/local/bin/pip注意我这里没有去动/usr/bin/python因为那是yum等系统工具的命根子。我是在/usr/local/bin里新建了python软链接由于/usr/local/bin通常排在/usr/bin前面终端里敲python就会走/usr/local/bin/python也就是Python 3而yum内部调用/usr/bin/python时走的还是系统Python 2。这样做的效果是——用户层面Python 2彻底消失了系统层面依赖Python 2的工具依旧正常运行。既不卸载又达成了让Python 2退役的目标。Ubuntu/Debian也类似。Ubuntu 18.04及以前自带Python 2很多系统维护命令依赖它。按上面思路装好新的Python 3后用update-alternatives这个机制来管理命令优先级其实更正规sudo update-alternatives --install /usr/bin/python python /usr/bin/python3.11 1 sudo update-alternatives --config python执行后可以通过选项切换默认python版本比直接软链接更安全。Ubuntu上有些老版本的apt包管理脚本也会调python所以不到万不得已不去apt remove python2。3.4 清理Python 2遗留的/Library、site-packages和PATH残余无论是Windows还是Linux卸载或隔离Python 2之后都有一些尸骸需要手动处理。这些残留物看起来不起眼但会时不时给你挖坑。首先是PATH残留。如果你的PATH变量里还有C:\Python27或/usr/bin/python2之前的旧路径命令解析就可能指向错误版本。检查并清理掉。其次是site-packages残留。Python 2时代装的第三方库会留在对应site-packages目录里卸载Python 2后这些目录依然存在它们对Python 3是无效的Python 2和3的包目录结构不同但会占地。Windows上一般是C:\Python27\Lib\site-packages删除整个Python 2安装目录即可Linux上如果卸载了python2相关包系统会清掉大部分但编译安装的Python 2可能还留在/usr/local/lib/python2.7手动删掉就行。macOS上手动安装的Python 2可能有好几个位置/Library/Frameworks/Python.framework/Versions/2.7、/usr/local/lib/python2.7等。删除前先确认哪个是Homebrew装的、哪个是官方pkg装的。Homebrew管理的可以用brew uninstall python2清理pkg安装的要用pkgutil --forget org.python.Python.Python-framework-2.7这样的命令注销否则系统记忆里始终认为它还在。最后还有一样东西容易被忽略——pip缓存和配置。~/.pip/pip.confLinux/mac或%APPDATA%\pip\pip.iniWindows里如果写了index-url等配置新pip一样会读取一般来说不影响。但~/.pydistutils.cfg这种老配置文件里的[install]字段可能导致Python 3的pip安装到奇怪目录发现异常时要记得删掉。4. 新旧版本共存期最容易踩的坑PATH优先级、pip错乱与虚拟环境实践4.1 pip明明装了包python却import不到的经典原因新装Python 3后你很可能遇到这样一个奇怪问题用pip install requests装了一个包然后再运行python脚本提示ModuleNotFoundError: No module named requests。我第一次遇到这问题时还以为是包没装上查了快半小时。后来发现pip命令和python命令指向的不是同一个Python解释器。可能pip是Python 3.11的pip而python因为PATH优先级的原因指向了某个旧版Python 3.6或者更倒霉——指向了残留的Python 2。解决办法很简单永远用解释器模块方式调用pip而不是单独敲pip命令。python3 -m pip install requestspython3 -m pip的意思是把pip当作Python 3.11的一个模块来运行。这样一来pip的安装目标100%和python3解释器一致绝对不会装错地方。这是Python生态里非常经典且安全的用法我后来所有环境都是这么装的再没出现过装完却import不到的问题。4.2 并发使用Python 2和3时pip的版本前缀规则在你还没下定决心卸载Python 2的时候系统里会同时存在两套pip。这种情况下命令的版本对应关系一定要记牢命令对应Python版本python取决于PATH优先级可能是Py2或Py3python2/python2.7Python 2.xpython3/python3.11Python 3.xpip取决于PATH优先级跟python一致pip2对应Python 2pip3对应Python 3python3 -m pip100%对应当前python3指向的解释器表里最关键的是最后一行。很多教程都会说用pip3装包但说实话pip3也不一定安全因为它可能被软链接指向一个你意料之外的Python 3子版本。而python3 -m pip中间不会转任何弯最靠谱。另外说个Windows上的小坑有些Windows机器里可能有多个Python 3版本微软商店版、官网版、Anaconda版各来一个。命令提示符里python到底跑哪个完全看PATH顺序。如果你装了Anaconda又装了官网python最好去环境变量里把不用的路径删掉否则一定会乱。4.3 为什么venv能在不碰系统Python的情况下隔离一切有了上一节的经验你可能会问那我是不是可以直接建一堆venv彻底绕开PATH带来的混乱答案是对这才是正规军的玩法。venv的原理是创建一个虚拟目录里面会生成一个bin/pythonWindows是Scripts/python.exe并且这个Python软链接会指向你创建venv时指定的那个Python 3解释器。激活venv后你的python和pip都被这个局部环境接管不会再受系统PATH影响。举个例子我在同一台服务器上同时维护了两个项目一个是数据分析平台要求Python 3.11 numpy 2.0另一个是自动化运维脚本要求Python 3.9 numpy 1.26。如果装在全局环境两个numpy版本必然打架。但分别建两个venv后两个项目的依赖完全是两个封闭世界互不干扰进程起来后各自用各自的环境无比清爽。再说一个实操细节创建venv的时候建议显式指定Python解释器避免系统默认的python3指向不明确。python3.11 -m venv /path/to/myproject_env这样这个venv就铁定绑定了Python 3.11。以后哪怕系统默认Python变成了3.12这个项目也还是按3.11跑不会被意外升级打破兼容性。4.4 等旧脚本全部迁移完成再卸载一个真实的迁移检查清单前面铺垫了这么多现在说回正题。你什么时候才算真正可以放心卸载Python 2我的判断标准不是我把它卸了而是我的所有工作流里已经找不到任何还依赖Python 2的环节。我整理了一份个人迁移检查清单你可以照着过一遍列出所有自己写的Python脚本逐一确认语法兼容Python 3。重点检查print语句、/除法、xrange、unicode、StringIO、except Exception, e这类老语法。用系统工具全局搜索一下有没有#!/usr/bin/env python或#!/usr/bin/python2这样的shebang头如果有改成#!/usr/bin/env python3。检查crontab定时任务、CI流水线、服务启动脚本看它们有没有写死python2或/usr/bin/python。在Python 3环境下逐一运行项目测试确认核心函数输出一致。编码问题尤其要仔细Python 2和3对字符串的默认处理逻辑完全不同。确认所有第三方库都有Python 3版本。这个可以直接到库的官方文档或PyPI上看Support Python Versions标签。检查有没有系统级依赖Python 2的工具会受影响。Linux下用rpm -qR python2或apt-cache rdepends python2再看看Windows下确认控制面板里卸载后没有其他软件报错。这份清单走完项目层面就基本不会被Python 2拖累了。此时再卸载或者继续让Python 2在系统里躺着不动Linux常见做法都不会影响你的日常开发了。5. 实际操作中容易被忽略的异常情况与排查心得5.1 官网下载极慢使用国内镜像源下载安装包很多小伙伴卡在第一步下载安装包———官网服务器在国外有时下载速度令人绝望。这里有个实用技巧。如果你想下载Python安装包可以把下载地址的域名替换成国内镜像。以华为云镜像为例下载链接结构是https://mirrors.huaweicloud.com/python/3.11.0/Python-3.11.0.tgz这样下载Linux源码包会快出天际。Windows安装包.exe也一样去找国内Python镜像的windows目录即可。另外下载时注意对比一下文件大小官网页面通常每版都会标注源码包大小如果下载下来小很多很可能是被截断了这种包装到一半会报错。5.2 python was not found; run without arguments to install from the Microsoft Store是Windows独有的提示不少人刚在Windows官网装完Python 3打开cmd一敲python却弹出这样一句提示python was not found; run without arguments to install from the Microsoft Store这不是报错也不是你没装好。这是Windows的应用执行别名App Execution Aliases在捣鬼。Windows商店会注册两个名为python.exe和python3.exe的假命令当你没有关闭商店版别名、且PATH里Python路径没排到前面时cmd就会撞上这两个假入口。解决办法有两种直接到设置 - 应用 - 高级应用设置 - 应用执行别名把python.exe和python3.exe两个开关关闭。这是最彻底的解法。在环境变量里把Python 3.11的路径和Scripts路径上移到PATH最顶部让真正的Python 3先被找到。我记得第一次遇到这个提示时一度以为电脑上Python没装成功后来仔细研究才发现是那个Microsoft Store版占位符的问题。如果你也遇到按上面两步处理就行。5.3 卸载Python 2后控制台输入python没反应或提示找不到命令Windows上卸载Python 2后再敲python提示不是内部或外部命令这种情况大概率是PATH里Python 2路径被删掉了同时Python 3的路径又没有正确添加进来。此时打开环境变量系统属性 - 环境变量 - Path - 编辑检查有没有Python 3安装目录和Scripts目录。没有就手动新增两条D:\Python311 D:\Python311\Scripts然后新开一个cmd窗口注意必须新开窗口旧窗口的环境变量不会自动刷新再验证python --version。Linux上如果python突然找不到命令检查一下是不是前面用软链接创建/usr/local/bin/python那一步没操作成功或者/usr/local/bin不在PATH里。执行echo $PATH看看如果没有/usr/local/bin把它加到PATH最前面即可。5.4 cc攻击源码等奇怪热词背后的真实需求不要尝试这些脚本我在整理这篇内容时看到搜索热词里有python cc攻击源码这类词必须多说一句。这里说的CC攻击本质是利用大量请求占用服务器资源的网络攻击行为在多数国家和地区都是违反法律法规的行为。用Python写这类攻击脚本没有任何建设性价值只会给自己惹麻烦。带着好奇心学习Python可以但请把精力放在正经方向上爬虫、数据分析、自动化办公、量化交易策略回测、机器学习这些方向远比研究攻击代码有价值。看到这类源码直接跳过就好。5.5 编码问题是最容易让旧脚本在Python 3下崩溃的隐形杀手Python 2时代字符串str是字节串unicode才是文本Python 3里str直接就是文本底层编码统一用Unicode。这就导致一个典型现象同一段处理中文字符串的代码在Python 2下运行正常迁移到Python 3后经常出现UnicodeDecodeError或输出乱码。有一次我迁移一个抓取网页标题的脚本Python 2下跑得好好的切到Python 3怎么都报错。查了半天发现是原来的代码里到处是# -*- coding: utf-8 -*-声明但处理时却用decode(gbk)把字节流强转成GBK——Python 3下这类多余的解码反而把正常的Unicode文本搞乱了。我的经验是迁移到Python 3后只要明确数据是文本就不要随便调用decode/encode让Python的str类型自己处理编码。用requests抓网页时res.text通常已经根据HTTP头正确解码了res.content才是原始字节流。能用text的绝不强行处理content。6. 一套完整的新环境初始化操作流程建议讲了这么多零散的坑最后给大家整理一个我自己在新电脑或新服务器上初始化Python环境的完整流程。这套流程经过了多次服务器和笔记本的验证照着做基本不会出问题。安装Python 3根据平台选择第2节的方式Windows用官网安装包并勾选PATHLinux用包管理器或源码编译macOS用pyenv。验证安装确认python3 --version输出正确确认python3 -m pip --version可用。清理PATH检查系统PATH里有没有旧Python路径确保新Python路径优先。处理Python 2判断是系统依赖还是独立安装Linux优先用替换优先路径而非卸载Windows如果没依赖可以正常卸载并清理残留。创建项目专用venvpython3.11 -m venv ~/venv/myproject source ~/venv/myproject/bin/activate在venv内安装依赖pip install --upgrade pip pip install -r requirements.txt建立pip国内镜像配置推荐大幅提升下载速度。在用户目录下创建~/.pip/pip.confLinux/mac或%APPDATA%\pip\pip.iniWindows[global] index-url https://pypi.tuna.tsinghua.edu.cn/simple trusted-host pypi.tuna.tsinghua.edu.cn测试项目脚本运行一遍核心脚本确认依赖、编码、路径都没有问题。记录版本信息执行下面命令把环境信息写进项目的README或文档里python --version pip list这套流程的核心理念就一句话先用新版本把自己的工作流跑顺再去考虑旧版本的卸载。在没有完全迁移之前Python 2卸载这件事可以无限期延后反正只要PATH优先级控制好Python 2躺在系统里也不会造成任何影响。我在实际操作中的体会是很多人折腾Python版本用力过猛反而把环境搞乱最后陷入卸了装上、装完又卸的循环。其实先想清楚为什么要升级、系统里谁还在依赖旧版本、项目代码有哪些兼容点按部就班走一遍一两个小时就能干净利落地搞定。