Jetson Orin Nano Pyhton默认版本切换
一. 准备知识1. 查找python位置语句whereis是 Linux 自带查找工具只搜系统标准录/bin、/sbin、/usr/bin、/usr/sbin、/usr/lib等系统预置路径不会搜自定义文件夹、虚拟环境、conda/pyenv。指定查看某个文件夹下存在哪些python文件可用如下命令2. 为了演示多版本python, 博主这边再安装一个其它版本1博主这里apt安装一个python 3.11功能# 1.安装PPA工具 sudo apt update sudo apt install software-properties-common ca-certificates -y # 2.添加Python第三方源 sudo add-apt-repository ppa:deadsnakes/ppa -y # 3.刷新缓存 sudo apt update sudo apt install -y python3.11 python3.11-dev python3.11-venv可看到两个版本都同时存在3.11并没有覆盖3.10注apt相关的基础知识见附录12我们再看下两个python下有哪些包分别执行对比python3.10 -m pip list python3.11 -m pip list可看到python3.11已经有很多包了而且很多包和之前就已经存在的python3.10一样。注关于包的一些基准知识见附录23博主安装完python3.11后使用python3 -m pip install --upgrade pip语句进行了升级。但引入了一个新问题python33.10pip/pip33.11。如下出现原因如下apt install python3.11只会在/usr/bin/新增python3.11不会修改软链接/usr/bin/python3所以敲python3依旧是系统默认 3.10。执行了python3.11 -m pip install --upgrade pip升级时没加 sudo默认带--user会把pip、pip3、pip3.11脚本生成到/home/jetson/.local/bin/PATH 优先级~/.local/bin排在/usr/bin前面 终端找命令时先匹配到家目录下的 pip这个脚本内部硬编码调用python3.11于是python3→ /usr/bin/python3 → 3.10pip / pip3→ ~/.local/bin/pip3 → 绑定 3.11这会引入一个很大的坑本来一个包想装到python3.10下的这么一弄装到3.11下去了。如下方法可以解决此问题删除用户目录下由--user生成的 pip 脚本rm -f ~/.local/bin/pip ~/.local/bin/pip3 ~/.local/bin/pip3.*执行后效果如下python和pip,pip3保持一致了建议安装或升级时就指定版本# 操作3.10 python3.10 -m pip list python3.10 -m pip install xxx # 操作3.11 python3.11 -m pip list python3.11 -m pip install xxx # 只在调用 python3.11 -m pip 时生效不生成 ~/.local/bin/pip3 python3.11 -m pip install --upgrade pip --no-user sudo python3.10 -m pip install --upgrade pip注后面可以养成如下好习惯永远不要直接裸敲pip/pip3做安装多 Python 环境统一用pythonX.X -m pip不要随便执行xxx -m pip install --upgrade pip不带--no-user极易覆盖系统 pip3开发项目一律用 venv 虚拟环境从根源隔离版本冲突。二. 5种切换方法对比1. 直接指定具体版本# 普通用户安装包放 ~/.local/lib/python3.10/site-packages python3.10 -m pip install 库名 # 全局所有用户安装sudo包放 /usr/local/lib/python3.10/dist-packages sudo python3.10 -m pip install 库名 # 示例装requests python3.10 -m pip install requests # 卸载 python3.10 -m pip uninstall requests -y# 用户私有安装 python3.11 -m pip install 库名 # 全局root安装 sudo python3.11 -m pip install 库名 # 给3.11装numpy1.24 python3.11 -m pip install numpy1.242. 使用~./bashrc中的路径切换对于在命令行语句下执行python文件时适用在文件底部添加语句alias python3/usr/bin/python3.11 alias python/usr/bin/python3.11 alias pip3python3.11 -m pip alias pippython3.11 -m pip别忘了执行source ~/.bashrc语句此时先执行语句python3 -m pip install --upgrade pip执行python3可看到已经是3.11版本了可看到pip和pip3都已经变成python 3.11的了。3. 使用软链接可借鉴博主之前的博客(主要是如下第1篇树莓派4B上多版本python切换一_在树莓派4上如何安装python2-CSDN博客Jetson TX2配置Tensorflow、Pytorch等常用库_jetson tx2 pytorch-CSDN博客Ubuntu下的基本知识点一_note, selecting libpython3.6-stdlib for regex p-CSDN博客如下能够查看各文件链接的情况ls -l /usr/bin之前apt-get安装完python3.11后, 还没安装对应的pip, 执行which pip3.11的时候是不显示路径的。如下语句可以实现安装sudo python3.11 -m ensurepip --upgrade- 后面是链接指向的真实文件观察可看到这里面是有多层软链接叫「链接链」支持无限多层嵌套/usr/bin/python 软链接指向 python3/usr/bin/python3 软链接指向 python3.10/usr/bin/python3.10 是真正可执行文件不是链接但不支持循环链接会报错比如a→bb→a如下语句只过滤出软链ls -l /usr/bin | grep ^l只输出软链接文件名find /usr/bin -type l同时显示链接指向的目标find /usr/bin -type l -lsstat 单独查看某个文件是否为软链接file 命令判断单个文件如上我们能看到当前python3,pip,pip3的状态我们执行如下三句软链接让其链接到指定版本上#把 /usr/bin/python3 这个软链接重新指向 python3.11实现全局默认 python3 切换为 3.11 版本。 #ln -s [源文件/源目录] [目标链接名] #顺序牢记源在前链接在后很多人写反踩坑 sudo ln -s /usr/bin/python3.11 /usr/bin/python3因为/usr/bin/python3已经指向一个源了所以我们一般在添加源之前先使用如下命令ls -l /usr/bin/python3查看下是软链接还是真实文件再删除可看到是被绑定了我们先删除这个源再绑定使用如下命令【仅是为了演示才去做这样的事情要知道这么操作后会使得很多绑定了python3的地方失效】sudo rm /usr/bin/python3到文件夹下看有个打叉的失效符号使用命令 ls -l /usr/bin 查看已经没有python3了之前图形里带叉的失效图标是缓存残留不用管实际文件不存在。/usr/bin/python3本身不是真实程序文件只是一个软链接你用rm删除它链接本身就直接消失了所以 ls 看不到。完毕后博主这边绑定下3.11版本sudo ln -s /usr/bin/python3.11 /usr/bin/python3可看到python3已经绑定为3.11版本了删除后由于博主不小心把所有终端都关闭了想再进入时终端打不开了。这是因为Jetson 底层桌面、gnome-terminal、apt、图形组件全部依赖/usr/bin/python3这个软链接你删掉后系统找不到 Python 解释器图形终端直接打不开。可按Ctrl Alt F3进入后先修复下软链接重新绑定回到3.10sudo rm /usr/bin/python3 sudo ln -s /usr/bin/python3.10 /usr/bin/python3下次记得如果只是演示演示完毕后终端不要关闭在终端里重新软链接回来后再去关闭终端。不然打开不了新的终端或者关机开启后容易引起异常。注系统出厂预装Python3.10所有系统图形工具、终端、apt、桌面组件配套的底层 C 扩展库只编译给 3.10 使用3.11 没有对应的系统绑定库全局软链接切到 3.11 直接崩溃。nome-terminal 崩溃关键gi 图形绑定库系统路径/usr/lib/python3/dist-packages/gi/里只有_gi.cpython-310m-aarch64-linux-gnu.so这个文件是图形界面依赖的底层模块仅适配 Python3.10。 当你把/usr/bin/python3链到 3.11 终端启动时会执行 Python 脚本尝试导入gi找不到 3.11 版本的_gi二进制文件直接闪退、打不开窗口。4. 开发环境指定Python版本或指定虚拟环境中的python版本参考博主之前博客树莓派4B上多版本python切换二_查看树莓派python环境-CSDN博客5. 使用update-alternatives非虚拟机环境下Ubuntu配置_ubuntu不安装虚拟机怎么用-CSDN博客6. 五种方法对比总结切换方式全局生效是否改动系统文件Jetson Nano 风险是否支持简写 python项目隔离能力推荐程度 (Jetson)直接指定 python3.11不全局按需指定无极低不支持必须带版本号无需配合 venv⭐⭐⭐⭐⭐ 首选bashrc 配置 PATH当前用户终端用户文件不碰系统低可实现无⭐⭐自定义用户软链接当前用户终端用户目录软链接低若是系统软链接指向风险极高支持 python 简写无⭐⭐⭐CMake / 编译指定 Python仅单次编译流程无极低不改变终端命令仅编译隔离⭐⭐⭐ 编译专用update-alternatives全系统全局所有程序修改 /usr/bin 系统软链接极高易损坏硬件依赖支持 python3 简写无全局隔离⭐ 不推荐虚拟环境 venv仅激活的 shell无任何系统修改无风险激活后可简写 python极强项目独立⭐⭐⭐⭐⭐ 项目开发标配一般情况下如果你是从中间开发商那边买的打包好的板子比如Jetson Orin Nano。里面既有原厂配好的环境也还有中间开发商配好的环境已经适配好/usr/bin/python3软链接、系统依赖、apt、系统脚本、开机服务全部绑定当前系统 Python能正常运行就完全没必要手动切换全局版本改全局反而大概率出各种隐性 bug。板子固件、串口脚本、开机自启程序、硬件驱动摄像头、GPIO、CAN、SDK很多写死/usr/bin/python3换版本后直接运行报错Ubuntu/Debian 包管理器apt内部大量依赖系统原版 Python改版本后apt install / apt update崩溃、安装软件失败中间厂商预编译的第三方库numpy、opencv、torch、硬件驱动包是针对原系统 Python 编译换版本会出现动态库找不到、导入报错上面提到了多种方式去切换版本最建议开发环境指定python版本特别是使用虚拟环境项目隔离最规范开发首选。此外调用时显示指定版本也是一种好方法。附录11. apt官方主推、最规范日常用法Ubuntu、Debian 新版官方文档指定交互式终端首选整合了apt-get apt-cache功能、彩色输出、进度条、提示更友好开箱即用、系统默认预装。aptitude 不是更规范只是功能更强的进阶工具。默认系统不带必须手动安装sudo apt install aptitude优势依赖冲突解析更强、卸载能自动清理无用依赖、自带全屏 TUI 文本界面浏览包定位解决依赖烂摊子的救场工具不是日常安装的标准规范aptitude有着如下优点处理依赖冲突、版本错乱时能给出多套解决方案很多apt解决不了的依赖报错用它能修复删除软件时自动移除不再需要的依赖包系统冗余更少直接输入aptitude进入可视化界面浏览、筛选、批量管理软件很方便但也有缺点不是系统标配换一台开发板大概率没有这个命令依赖求解策略偏激进偶尔会建议卸载大量系统核心包手快确认容易搞崩系统教程、官方运维文档几乎默认用aptaptitude 属于老派管理员小众工具如下博客中也有提到aptitudeUbuntu下的基本知识点一_note, selecting libpython3.6-stdlib for regex p-CSDN博客2. 所有 Debian/Ubuntu包括 Jetson Nano严格遵循FHS 3.0规范这套标准统一规定了系统文件存放位置apt/dpkg打包软件时就写死路径不能随便改/usr Unix System Resources系统预装、包管理器管理的软件总目录/usr/bin存放所有普通可执行二进制程序/usr/lib存放程序配套动态库、Python 标准库、模块/usr/share文档、配置、图标、man 手册等静态资源。而/home/用户名是单用户私有空间只存放用户手动安装、隔离环境不属于 apt 的管理范围。只有非 apt 安装才会在这里仅当前普通用户生效sudo、系统服务不识别不影响系统底层工具风险极低。用apt-get install python3.x安装多个 Python 小版本不会互相覆盖完全并行共存一。apt 给每个 Python 次版本分配完全独立目录文件互不冲突。可看到可执行程序是分开的。标准库目录也是完全隔离的。pip 工具独立 分别生成pip3.10、pip3.11安装第三方包时各自写入对应版本的库目录不会混/usr/bin/python3只是软链接不是真实程序本体只有你手动修改这个链接时才会改变默认调用版本不会改动任何一个 Python 本体文件。附录21. Python的包主要来自如下几个方面1Python 标准内置库所有版本自带每个 Python 解释器自带标准库os/sys/json/socket/sqlite3等这是语言内置和系统无关3.10、3.11 各自都有一套。Debian/Ubuntu 做了特殊路径设计Python 3.x 所有版本共用纯 Python 系统包目录全局共享 apt 纯库/usr/lib/python3/dist-packages2) 存放apt install python3-xxx安装的纯 Python 库无 C 扩展如 requests、yaml、six所有 python3.10 /python3.11 /python3.12 都会自动把这个目录加入sys.path这里的包不分版本3.10 装的3.11 直接 import这就是你看到 “混在一起” 的根源版本专属 apt 扩展库/usr/lib/python3.X/dist-packages带 C 编译扩展的库numpy、opencv、pyqt、cryptographyABI 不兼容分版本存放/usr/lib/python3.10/dist-packages→ 仅 3.10 可见/usr/lib/python3.11/dist-packages→ 仅 3.11 可见 这类包不会跨版本共享。3) 用户 pip 安装目录完全隔离全局 pip/usr/local/lib/python3.X/dist-packages当前用户 pip~/.local/lib/python3.X/site-packages每个版本独立互不互通用python3.10 -m pip装的包3.11 看不见。拿python3.10举例会有这么多路径来存放sit-packages玩的真花啊pythonX.X -m pip list会读取当前 Python 解释器的sys.path依次遍历每一条路径下的包汇总展示虚拟环境内部 site-packages如有PYTHONPATH 里的自定义路径你的 ROS install 包目录用户私有~/.local/lib/python3.11/site-packages全局 sudo pip/usr/local/lib/python3.11/dist-packages版本专属 apt 扩展/usr/lib/python3.11/dist-packages全版本共享 apt 纯包/usr/lib/python3/dist-packages只要路径存在于sys.path里面安装的包都会被一并列出。执行如下语句python3.10 -m pip list python3.10 -c import sys; [print(p) for p in sys.path] pip show pythonpackagedemo1可看到例举出的Python包里有博主之前写的ros2包python,能快速查看当前 Python 全部搜索路径查看查看包安装路径确认归属该 Python也能一眼就能区分是源码编译的 ROS 包不是 pip/apt 安装的第三方包。两种特殊情况不会被列出其他 Python 版本专属目录 比如/usr/lib/python3.10/dist-packages、~/.local/lib/python3.10/site-packages不在 python3.11 的 sys.path执行pip311 list完全看不到。虚拟环境加了--system-site-packagesfalse创建环境时关闭读取系统包此时pip list只会显示虚拟环境内部的包屏蔽所有系统、用户目录的包。# 创建完全不读取系统全局包的纯净虚拟环境 python3.11 -m venv --without-pip --system-site-packagesfalse ~/py311_clean注包重名时的覆盖规则Python 按sys.path列表从前到后依次查找找到第一个匹配包就停止后面同名包直接被忽略。 完整优先级从高到低你 JetsonROS2 环境当前虚拟环境site-packages激活 venv 时第一顺位PYTHONPATH自定义路径ROS2 install 的 python 包目录用户本地包~/.local/lib/python3.X/site-packagesroot 全局 pip/usr/local/lib/python3.X/dist-packages版本专属 apt/usr/lib/python3.X/dist-packages全版本共享 apt/usr/lib/python3/dist-packagesPython 内置标准库os/sys/json 等优先级最高任何第三方都覆盖不了2. 如下是几种安装方式的比较安装方式存放路径是否跨 3.x 版本共享管理工具破坏系统风险补充特点1. apt install python3-xxx无版本号纯 Python 包/usr/lib/python3/dist-packages✅ 全 3.10/3.11/3.12 共享apt⭐⭐⭐⭐⭐ 极高系统底层工具依赖严禁 pip 修改pip 升级会直接搞崩 apt、软件中心2. apt install python3.10-xxx带版本C 扩展包/usr/lib/python3.10/dist-packages❌ 仅 3.10 可用apt⭐⭐⭐ 中等ABI 不兼容分版本存放只能对应版本 importpip 改动易冲突3. sudo python3.X -m pip install xxx/usr/local/lib/python3.X/dist-packages❌ 仅对应 X 版本pip⭐⭐⭐⭐ 高全服务器用户可见优先级高于 apt 包容易覆盖系统 apt 依赖新版 Ubuntu 会触发 externally-managed 保护4. python3.X -m pip install xxx无 sudo--user~/.local/lib/python3.X/site-packages❌ 仅当前用户 对应 X 版本pip⭐⭐ 较低只当前用户生效不影响 root / 其他用户你当前 pip3 绑定的就是这个路径5. colcon build ROS2 自定义 Python 包source install/setup.bashws/install/包名/lib/pythonX.X/site-packages❌ 仅对应编译时的 Python 版本colcon手动管理 build/install⭐⭐⭐ 中等靠 PYTHONPATH 临时加载多工作空间叠加 source 极易包重名覆盖pip 无法卸载6. python3.X -m venv 虚拟环境内 pip 安装xxx_env/lib/pythonX.X/site-packages❌ 完全隔离不读取系统包默认关闭 system-site-packagespip⭐ 极低推荐开发独立环境不污染系统任何目录彻底杜绝跨版本、apt 冲突由于Debian/Ubuntu 独特的dist-packages全局共享机制的存在导致耦合性强。推荐最佳实践避免包混乱开发一律用虚拟环境隔离