☰
ModuleNotFoundError: No module named ‘orjson‘ 报错排查与解决全指南
2026/10/8 3:27:23 网站建设 项目流程

搞 Python 的人,十个里有九个都见过ModuleNotFoundError这个红字,而No module named 'orjson'又是里面特别能折腾人的一个。它经常藏在pip install某一个大包的时候突然蹦出来,前面刚装了一堆依赖,眼看就要成功了,结果给你一记当头棒喝。还有更隐蔽的情况:依赖装得干干净净,一跑程序照样报这个错,查了半天才发现是环境串了。

这篇文章就把这个报错从头到尾拆一遍,从报错本身是什么含义,到 orjson 为什么会被卷入安装过程,再到各种场景下的具体解法,最后附上一份我实际排查时的完整记录和踩坑速查表。不管你是刚入门 Python 的初学者,还是已经在用 FastAPI、Pandas 这类重度依赖库的开发者,按着这篇文章的思路走,基本都能一次解决。

1. 报错链路拆解:No module named 'orjson' 到底怎么来的

1.1 从报错信息反推 Python 的模块查找机制

先把这句话翻译成人话:ModuleNotFoundError: No module named 'orjson'的意思是,Python 解释器在执行 import 语句时,按照自己的一套搜索路径找了一圈,没找到名字叫orjson的模块,于是抛出了异常。

Python 找模块的路径顺序大致是:当前脚本所在目录、PYTHONPATH环境变量指定的路径、标准库目录、site-packages 里安装的第三方库目录。你可以用几行代码随时看自己环境里到底有哪些搜索路径:

import sys for idx, path in enumerate(sys.path): print(idx, path)

如果 orjson 已经装上了,但解释器还是找不到,那就说明报错的这个解释器和安装包时用的解释器不是同一个。这就是后面要反复强调的一个重点:报错是哪个 Python 解释器在跑,它到底去哪里找包,先搞清楚这个,问题就解决了一半。

再补充一个和 3.6 版本相关的背景知识:ModuleNotFoundError是 Python 3.6 开始从ImportError里细分出来的子类。所以你在老代码里可能还会看到ImportError: No module named orjson,这是历史版本差异,含义完全一样,排查思路也完全相同。

1.2 报错位置不同,问题性质完全不同

同样是这个报错,出现在不同阶段,根因可能差得很远。我一般先分两类:一类是安装时报错,另一类是运行时报错。

安装时报错最典型的情况是:你在执行pip install 某个包的时候,pip 去下载和构建这个包,包里的 setup 脚本或构建钩子里import orjson,但当前环境里没有,于是一整条安装链路直接中断。这种情况在安装从 GitHub 拉下来的源码包、或者本地开发中尚未发布成 wheel 的包时特别常见,因为源码包往往需要在构建阶段执行 Python 代码去读取配置或生成文件。

运行时报错更普遍:pip install已经成功结束,甚至pip list里也能看到 orjson,但一执行python main.py就报错找不到模块。这种问题的八成原因是环境错位——系统里有多个 Python,或者虚拟环境没激活,安装是装到 A 解释器里了,运行时却用的是 B 解释器。

如果运行时报错发生在虚拟环境内部,还有一种隐蔽情况:项目目录里恰好有一个文件叫orjson.py,或者你自己写过一个同名模块。这时候 Python 会在 sys.path 的当前目录优先命中的是自己的文件,而不是 site-packages 里的真 orjson,于是要么导入失败,要么导入了一个缺各种属性的假模块。这个问题排查起来非常迷惑,后面实操部分我会专门展开。

2. 为什么装个包会牵扯出 orjson:依赖链背后的安装机制

2.1 orjson 是什么,谁离不开它

先给不认识 orjson 的读者补个背景。orjson 是一个用 Rust 编写的高性能 JSON 序列化库,官方文档的基准测试里,它序列化和反序列化的速度通常是标准库json的好几倍。因为性能亮眼,很多追求速度的第三方库会把它作为可选或必选的依赖。

Web 框架里,FastAPI 和 Starlette 生态对 orjson 的支持做得比较深,开启后 JSON 响应可以直接让 orjson 处理,高并发场景下能把序列化这块的 CPU 开销压下去不少。数据处理和爬虫领域里,也有不少库在解析大量 JSON 时选择 orjson 做底层加速。

所以当你pip install某个库时,pip 看了一眼这个库的install_requires或依赖声明,发现它import orjson或者声明了orjson>=某个版本,就会顺手把 orjson 拉进安装列表。正常情况下你根本不会注意到,但一旦网络抖动、版本冲突、或者走的源里没有对应系统的二进制包,orjson 就成了最显眼的那个报错点。

需要说明的是,orjson 并不是所有场景的必需品,纯标准库写的项目完全可以不碰它。它大多是被间接依赖带进来的,这也是很多人报错时一头雾水的原因——明明自己从来没主动装过 orjson,怎么就被它卡住了。

2.2 pip 解析依赖与构建时的暗坑

pip 的依赖解析逻辑,在普通场景下是透明的:读元数据、算版本、下载、安装。但这里有两个暗坑,是我排查时重点看的。

第一个暗坑是源码包构建阶段依赖。很多库在发布时只提供 sdist(源码包),没有提供当前系统对应的 wheel 包。pip 要安装这种包就会先构建,构建工具的配置文件(比如 pyproject.toml 里的build-system.requires)里如果写了一堆构建依赖,而这些依赖又没提前装进环境,构建就会在中途报错。如果那个库的构建脚本里恰好引到了 orjson,报错信息就会包含No module named 'orjson'。

第二个暗坑是版本回溯。pip 在某些情况下为了满足整个依赖树的版本要求,会先安装一个 A 版本,之后发现和另一个包冲突又降级成 B 版本。这个过程中如果某个环节的 wheel 不可用,pip 可能把已装好的包卸载掉,但依赖它的其他模块还在别的地方继续引用,最终导致运行时报No module named 'orjson'。看起来是玄学,实际是版本解析留下的烂摊子。

提示:遇到这种诡异的依赖链问题,先别急着单个装 orjson。看清楚完整报错上下文里 pip 正在处理哪个包,大概率真正的根因在那个包身上,而不是 orjson 本身。

除此之外,Python 版本兼容性也值得留意。orjson 这类带 Rust 扩展的库,对不同 Python 版本的支持窗口是有限的。如果你用的是比较老的 Python 版本,pip 在解析时可能找不到匹配的预编译 wheel,就会尝试从源码编译,而源码编译需要 Rust 工具链和一堆构建依赖,环境里没有的话又是一串连环报错。

3. 对症下药:从临时修复到根除的四个方案

3.1 方案一:先把 orjson 装进当前环境

最直接的办法,就是手动安装缺失的模块。打开终端,执行:

pip install orjson

如果当前环境里已有多个 Python 或虚拟环境,建议用更精确的写法,直接指定用哪个解释器安装:

python -m pip install orjson

这里用python -m pip而不是裸pip install是有讲究的。裸pip对应的是 PATH 里排在最前面的那个 pip,它可能指向 A 解释器;而你直接跑python xxx.py用的可能是 B 解释器。python -m pip保证安装动作和你之后运行代码用的解释器是同一个。

装完之后验证一下:

python -c "import orjson; print(orjson.__version__)"

能打出版本号,说明这个环境下 and 可以正常 import,基础问题解决。如果这里还报错,说明环境本身有问题,直接跳到方案四用虚拟环境隔离。

3.2 方案二:升级 pip 与 setuptools,修复依赖解析

如果你是在安装某个大包的过程中报错,装完 orjson 之后很可能还会在下一个依赖上再次卡住,因为根本问题是 pip 的依赖解析逻辑或构建工具太旧。这种情况下,先把基础工具升级一轮:

python -m pip install --upgrade pip setuptools wheel

升级之后再重新执行之前失败的安装命令,很多时候就不会再报同样的问题了。

为什么升级这几样东西有用?旧版本 pip 对 PEP 517/518 构建协议的支持不完善,遇到采用新式 pyproject.toml 声明的包,构建过程容易出幺蛾子。setuptools 版本太老,则可能导致某些包的元数据读取异常,间接造成依赖缺失的假象。wheel 包如果没有及时更新,在本地构建和缓存利用上也可能有兼容性问题。

这类问题的典型特征是:报错信息里的缺失模块每次不一样,这次是 orjson,上一次可能是 pydantic,再上一次是 attrs。看到这种“不固定缺失模块”的规律,基本可以断定不是 orjson 的锅,而是工具链老化,升级完立刻见效。

3.3 方案三:锁定版本与 requirements.txt 基建

orjson 本身也在持续迭代,不同版本对不同系统的支持有差异。如果安装时 Network 波动导致下载了一半,或者某次缓存坏了,常规的pip install orjson可能反复失败。这时候可以显式指定版本安装:

pip install "orjson==3.9.10"

指定版本有两个好处:一是避开最新版可能的兼容性问题,二是走 pip 的缓存机制时,同一个版本的元数据可以直接复用,减少重复下载。具体版本号可以去 PyPI 的 orjson 页面查,挑一个稳定且和你的 Python 版本匹配的即可。

更推荐的做法是把这个依赖写进项目的 requirements.txt:

orjson==3.9.10 fastapi==0.111.0 uvicorn==0.30.1

然后统一安装:

pip install -r requirements.txt

把依赖版本锁死,是避免“这次能跑、下次重装就报错”的关键。现实世界里,直接pip install 包名装出来的是一个不固定版本,过了半年再装可能就是另一个版本,连带依赖也跟着变,报错只是时间问题。锁版本虽然不能完全避免依赖冲突,但至少给了你一个稳定可复现的起点。

3.4 方案四:用虚拟环境隔离依赖污染

这一条是长期的根治方案,也是最推荐在生产环境或正经项目里使用的方案。Python 项目最忌讳的就是把所有依赖都堆在全局环境里,时间一长,和系统自带的 Python 包相互污染,或者不同项目对同一个包要求不同的版本,直接冲突到不可收拾。

标准做法是给每个项目建独立虚拟环境:

python -m venv venv

创建之后激活:

Windows 下:

venv\Scripts\activate

Linux 和 macOS 下:

source venv/bin/activate

激活之后,命令行提示符前面会出现(venv)字样,这时候再执行 pip install,所有包都会装进这个虚拟环境,跟系统环境完全隔离。跑程序时只要保证是在同一个终端会话里,用同一个解释器,就不会再出现“装到了 A、跑在 B”的错位。

如果连 venv 都用得不顺,还可以考虑 conda 或者 uv 这类更现代的环境管理工具。conda 的优势在于不仅管 Python 包,还能管不同版本的 Python 解释器;uv 则是这两年热度飙升的工具,安装快、并发度高、依赖解析准确,主打的就是一个省心。工具的选择看个人习惯,但“每个项目一套环境、依赖显式声明”这个原则是通用的。

注意:不要轻易直接用sudo pip install orjson往系统 Python 里猛装包,尤其是 Linux 发行版自带的 Python。系统包管理器管理的那一套环境,被 pip 动过之后很容易出问题,重则把系统组件搞坏。遇到权限问题,优先考虑用户级安装或虚拟环境。

4. 一次完整的排查与修复实操记录

4.1 事件复现与初始判断

上周我在一台新配的 Linux 服务器上部署一个基于 FastAPI 的服务,克隆代码后按照 README 执行:

pip install -r requirements.txt

日志一路滚得很顺利,装到某个阶段突然中断,核心报错就是:

ModuleNotFoundError: No module named 'orjson'

因为 requirements.txt 里并没有 orjson,我第一反应是某个间接依赖引到了它。于是没急着去下载 orjson,而是先打开完整日志往回翻,找到 pip 此刻正在处理的那个包,发现是一个内部数据处理库,它的元数据里声明了对 orjson 的依赖。

初始判断有两个方向:一是这个库的依赖没被 pip 正确解析到,二是解析到了但下载环节出了问题。由于日志里能看到 pip 已经下载了不少包,网络基本通,我倾向于先把依赖解析这块排查清楚。

4.2 逐层排查的具体过程

第一步,确认当前环境里有没有 orjson:

pip show orjson

返回为空,确认缺失。

第二步,确认当前 Python 解释器路径,和 pip 指向的是不是同一个解释器:

which python which pip python -m pip --version

实际输出里,python指向/usr/bin/python3,pip也指向对应的解释器,排除了环境错位。但既然报错发生在安装中途,而不是运行阶段,环境错位本来就不是主要嫌疑对象。

第三步,检查 pip 版本:

python -m pip --version

发现服务器上带的 pip 还是 20.3 版本,这个版本对新版 pyproject.toml 构建协议的支持确实不够完善,属于老毛病了。于是先升级工具链:

python -m pip install --upgrade pip setuptools wheel

升级完成之后重新执行pip install -r requirements.txt,这次没有在 orjson 上报错。

这里要说明一下:升级 pip 不是必然能解决所有情况,但在这个案例里,老版本 pip 对某些依赖元数据的解析存在缺陷,导致 orjson 的依赖没有被正确拉取和安装,所以报错才会出现在安装阶段。升级后 pip 的依赖解析能力提升,这个问题就消失了。

4.3 修复验证与收尾

重新安装完成后,做三件事验证:

第一,确认依赖树完整:

pip list | grep orjson

能看到 orjson 且版本号符合预期。

第二,确认可以正常导入:

python -c "import orjson; print(orjson.__version__)"

输出版本号无异常。

第三,启动服务做一次端到端验证。服务起来之后,调一个返回 JSON 的接口,响应正常,之前的报错没有再出现。

最后我把修复动作沉淀进了项目文档:部署第一步升级 pip 工具链、requirements.txt 显式锁定关键依赖、必要时用虚拟环境隔离。这套操作下来,后续再换机器部署,就没在这个环节上踩过第二次坑。

5. 常见问题排查表与独家避坑技巧

5.1 高频症状对照表

整理这份速查表的时候,我把这些年见过的报错场景大致归了几类,方便你对症下手:

症状可能的根因首选排查动作
运行代码时报缺少 orjson,但之前没主动装过间接依赖未正确安装pip show orjson,缺失则安装
pip install 过程中报缺少 orjson依赖解析异常或构建阶段 import升级 pip/setuptools 后重装
安装时下载很慢或超时失败网络原因或当前源不稳定切换国内镜像源重试
import 报错,但 pip show 显示已安装多个解释器环境错位which python对比which pip
项目目录里存在 orjson.py 文件同名文件遮蔽真实模块rename 该文件,清空pycache
安装 orjson 时提示需要 Rust 编译平台无预编译 wheel 包安装 Rust 工具链或更换平台
升级 pip 后安装成功,但运行仍报错虚拟环境未激活或激活了错误环境source venv/bin/activate后重装

镜像源这行多说一句:如果你在国内网络环境,默认的 PyPI 源偶尔会抽风,装大包或者带二进制扩展的包时尤其明显。换一个国内镜像能省不少时间:

pip install orjson -i https://pypi.tuna.tsinghua.edu.cn/simple

这种切换只是把下载源改了,不影响包的内容和兼容性。如果项目有统一的依赖文件,也可以在 pip.conf 或环境变量里把默认源改掉,一劳永逸。

5.2 排查路径与几个我踩过的坑

排查这个报错,我的建议是严格按住以下顺序来,不要跳步:

  1. 看清报错是发生在pip install阶段还是程序运行阶段,这两个方向不同。
  2. which python和which pip同时跑,确认解释器是否统一。
  3. pip show orjson看当前环境到底装没装,装了是什么版本。
  4. python -c "import orjson"直接试探导入,看报错是否复现。
  5. 如果导入报错且 pip 显示已安装,去项目目录找有没有叫 orjson.py 的文件,或检查sys.path有没有被改过。

第 5 步是很多人栽跟头的地方。我自己遇到过一次:项目根目录下不知道谁放了一个工具脚本叫orjson.py,从网上复制下来想改改用,结果这个文件直接把真正安装的 orjson 给“遮蔽”了。Python 导入模块时优先看的是当前脚本目录,于是每次 import 进来的都是这个半吊子文件,自然各种报错。排查了大半天,最后用python -c "import orjson; print(orjson.__file__)"一看路径指向了项目根目录,才恍然大悟。这个命令在排查所有“已安装但 import 不对”的情况下都很好用,因为 print 出来的文件路径能直接告诉你解释器到底加载了哪个文件。

另外还有一个习惯值得养成:pip install装完第三方库后,顺手用import验证一次。这一步耗时几乎可以忽略,但能立刻发现问题,避免在“以为装好了”的错觉里继续往深了写代码。很多人是在写了几百行业务代码之后才被 import 报错打断,回头才发现当初那个包根本没装上,返工成本极高。

如果你在团队协作项目里,还有一个小建议:把环境版本信息固化下来。一个项目里至少要有 requirements.txt,更多人会选择加一个包含完整依赖锁定版本的 requirements-lock.txt,甚至直接用 Poetry 或 PDM 这类工具管理依赖。锁定版本的意义在于,你的同事、未来的你、CI 服务器,任何人在任何时候重装环境,得到的结果都与开发时一致,不会凭空多出或缺少某个依赖。orjson 这次报错,本质上就是环境一致性和依赖解析链的问题,解决思路也适用于其他任何No module named 'xxx'报错。

最后再分享一个我实际验证过的小技巧:当你怀疑是 pip 缓存导致安装结果不对时,可以先执行pip cache purge清空缓存,再重新安装。这个操作可以解决一部分“下载了但内容不完整”引起的诡异问题,成本低、无副作用。我后来在多个项目里都把它列在“环境重装”的标准操作里,效果一直很稳定。

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

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

立即咨询