在 Python 中处理 JSON 时,是否保持字段顺序取决于两个因素:
- JSON 解析后使用的数据结构
- Python 版本
下面从 JSON规范 → Python实现 → 常见方案 → 最佳实践进行系统说明。
一、JSON 标准本身是否保证顺序?
根据 RFC 8259:
JSON object 是 unordered collection of name/value pairs
也就是说:
JSON 标准理论上不保证字段顺序。
例如:
{
"a": 1,
"b": 2,
"c": 3
}
在语义上等价于:
{
"c": 3,
"a": 1,
"b": 2
}
但是:
现实系统(API / 配置文件 / 前端)通常会依赖顺序。
二、Python 3.7+ 的默认行为
从 Python 3.7 开始:
dict
保证插入顺序(insertion order)。
这一行为最早在 Python 3.6 的 CPython 实现中出现,并在 Python 3.7 成为官方语言规范。
示例:
import json
data = json.loads('{"a":1,"b":2,"c":3}')
print(data)
输出:
{'a': 1, 'b': 2, 'c': 3}
顺序保持。
因此:
Python 3.7+ 默认就能保持 JSON 字段顺序。
三、Python 3.6 以下版本解决方案
在旧版本中需要使用:
OrderedDict
来自:
collections
示例:
import json
from collections import OrderedDict
data = json.loads(
'{"a":1,"b":2,"c":3}',
object_pairs_hook=OrderedDict
)
print(data)
结果:
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
关键参数:
object_pairs_hook
它接收:
[(key,value),(key,value)]
再转换为指定结构。
四、JSON 序列化保持顺序
当 Python → JSON 时:
import json
data = {
"name": "Alice",
"age": 20,
"city": "Tokyo"
}
print(json.dumps(data))
输出:
{"name": "Alice", "age": 20, "city": "Tokyo"}
顺序与插入顺序一致。
如果想 按字典序排序:
json.dumps(data, sort_keys=True)
输出:
{"age":20,"city":"Tokyo","name":"Alice"}
五、读取 JSON 时强制保持顺序
完整写法:
import json
from collections import OrderedDict
with open("data.json") as f:
data = json.load(
f,
object_pairs_hook=OrderedDict
)
这样即使:
- Python旧版本
- 第三方解析
也能保持顺序。
六、处理 JSON Schema / API 时的常见需求
很多场景需要 字段顺序固定:
例如:
1 API返回
{
"code": 200,
"message": "ok",
"data": {}
}
可以使用:
from collections import OrderedDict
resp = OrderedDict()
resp["code"] = 200
resp["message"] = "ok"
resp["data"] = {}
2 配置文件
例如:
{
"database": {},
"redis": {},
"logging": {}
}
配置文件通常希望 按逻辑顺序显示。
七、更快的 JSON 库(保持顺序)
一些高性能 JSON 库也保持顺序:
1 orjson
orjson
特点:
- Rust实现
- 超快
- 保持 dict 顺序
示例:
import orjson
data = orjson.loads(b'{"a":1,"b":2}')
2 ujson
UltraJSON
import ujson
data = ujson.loads('{"a":1,"b":2}')
也保持顺序(Python3.7+)。
八、JSON字段顺序陷阱
1 dict 合并
a = {"a":1,"b":2}
b = {"c":3}
c = {**a, **b}
结果顺序:
a b c
2 更新字段
d = {"a":1,"b":2}
d["a"] = 100
顺序 不会改变。
3 删除再插入
del d["a"]
d["a"] = 1
顺序变为:
b a
九、最佳实践
现代 Python 推荐:
✔ Python 3.7+
直接使用:
dict
✔ 需要严格顺序
使用:
OrderedDict
✔ 读取 JSON
json.load(..., object_pairs_hook=OrderedDict)
十、一句话总结
Python 处理 JSON 保持字段顺序的方法:
| 方法 | 适用版本 |
|---|---|
| dict | Python ≥3.7 |
| OrderedDict | Python ≤3.6 |
| object_pairs_hook | 强制顺序 |
核心代码:
json.loads(json_str, object_pairs_hook=OrderedDict)
如果你愿意,我可以继续讲一个 很多 Python 工程师都忽略但在真实项目里很重要的问题:
“为什么有些 JSON 在 Python 里顺序会突然乱掉?”
(涉及 dict重建、ORM序列化、FastAPI/Pydantic内部实现)。