Python中的JSON工具库

 

1、原生json库

json是Python内置标准库,开箱即用。json库也非常简单,就两组序列化(编码)、反序列化(解码)方法。

基本使用

1)Python对象与JSON字符串的互相转化:

import json

data = {"name": "Alice", "age": 30, "is_active": True}

# json.dumps将 Python 对象转为 JSON 字符串
json_str = json.dumps(data)
print(json_str)  # {"name": "Alice", "age": 30, "is_active": true}

# json.loads将JSON 字符串转为 Python 对象
parsed = json.loads(json_str)
print(parsed)  # {"name": "Alice", "age": 30, "is_active": true}

以下是Python 类型与JSON 类型的转化对照,注意json 库无法直接处理datetime, Decimal, UUID 等常用内建类型以及自定义类对象。

Python 类型 JSON 类型
dict object
list, tuple array
str number
True / False true / false
None null









2)JSON文件的读取与写入:

#json.dump写入 JSON 到文件
with open('data.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, indent=2)

#json.load从文件读取 JSON
with open('data.json', 'r', encoding='utf-8') as f:
    loaded = json.load(f)

注意json 库处理超大 JSON 文件时(如 GB 级),json.load() 会一次性读取内存,效率低甚至崩溃。 

具体参数说明:

参数名 说明
indent=2 美化输出(缩进)
sort_keys=True 字典按 key 排序输出
ensure_ascii=False 输出非 ASCII 字符(如中文)
default=function 自定义无法序列化对象的处理方式

 

 

 

 

 

 

2、simplejson

simplejson 是 Python 的一个第三方 JSON 库,是标准库 json 的超集,提供更强大的功能与兼容性。它最初就是标准库 json 的前身,所以用法非常相似,但提供了更多扩展选项(如精度控制、Decimal 支持、自定义编码等)

安装

pip install simplejson

基本使用
simplejson也包含了loads\load,dumps\dump两组序列化(编码)、反序列化(解码)方法,且使用方法与内置的json库一模一样。
  

import simplejson as json


data = {"name": "Alice", "age": 30, "is_active": True}

# json.dumps将 Python 对象转为 JSON 字符串
json_str = json.dumps(data)
print(json_str)  # {"name": "Alice", "age": 30, "is_active": true}

# json.loads将JSON 字符串转为 Python 对象
parsed = json.loads(json_str)
print(parsed)  # {"name": "Alice", "age": 30, "is_active": true}

使用 Decimal 类型,simplejson支持Decimal类型的序列化与反序列化:  

import simplejson as json

from decimal import Decimal

data = {'price': Decimal('19.99')}

# 支持 Decimal(不会强制转 float)
json_str = json.dumps(data, use_decimal=True)
print(json_str)  # {"price": 19.99}

# 正确解析为 Decimal
parsed = json.loads(json_str, use_decimal=True)
print(parsed)  # {'price': Decimal('19.99')}

 

3、orjson、ujson与rapidjson

安装

pip install orjson
pip install ujson
pip install python-rapidjson

orjson用法:

import orjson


data = {"name": "Alice", "age": 30, "is_active": True}

# json.dumps将 Python 对象转为 JSON 字符串
json_str = orjson.dumps(data)
print(json_str)  # b'{"name":"Alice","age":30,"is_active":true}'

# json.loads将JSON 字符串转为 Python 对象
parsed = orjson.loads(json_str)
print(parsed)  #{'name': 'Alice', 'age': 30, 'is_active': True} 

ujson用法:

import ujson


data = {"name": "Alice", "age": 30, "is_active": True}

# json.dumps将 Python 对象转为 JSON 字符串
json_str = ujson.dumps(data)
print(json_str)  # {"name":"Alice","age":30,"is_active":true}

# json.loads将JSON 字符串转为 Python 对象
parsed = ujson.loads(json_str)
print(parsed)  # {'name': 'Alice', 'age': 30, 'is_active': True}  

rapidjson用法:

import rapidjson


data = {"name": "Alice", "age": 30, "is_active": True}

# json.dumps将 Python 对象转为 JSON 字符串
json_str = rapidjson.dumps(data)
print(json_str)  # {"name":"Alice","age":30,"is_active":true}

# json.loads将JSON 字符串转为 Python 对象
parsed = rapidjson.loads(json_str)
print(parsed)  # {'name': 'Alice', 'age': 30, 'is_active': True}

orjson、ujson、rapidjson与json区别:

import orjson, ujson, rapidjson, json
import time

data = [{"id": i, "name": f"user{i}", "active": True, "score": i * 0.5} for i in range(100000)]


def test(lib, dumps_func, loads_func):
    t1 = time.time()
    s = dumps_func(data)
    t2 = time.time()
    obj = loads_func(s)
    t3 = time.time()
    print(f"{lib}: dumps={t2 - t1:.4f}s, loads={t3 - t2:.4f}s")


test("orjson", orjson.dumps, orjson.loads)
test("ujson", ujson.dumps, ujson.loads)
test("rapidjson", rapidjson.dumps, rapidjson.loads)
test("json", json.dumps, json.loads) 

性能结果区别:

orjson: dumps=0.0150s, loads=0.0319s
ujson: dumps=0.0539s, loads=0.0578s
rapidjson: dumps=0.0598s, loads=0.1167s
json: dumps=0.0997s, loads=0.0768s 
库名dumps 时间loads 时间总体性能评价
orjson 🥇 最快(~0.09s) 🥇 最快(~0.08s) 🚀🚀🚀 超高速
ujson 次快(~0.13s) 次快(~0.12s) 🚀🚀 快
rapidjson 稍慢(~0.18s) 稳定(~0.15s) 🚀 中等
json(内置) 🐢 ~0.27s 🐢 ~0.23s 🐢 慢

 

 

 

 

 

 

 

 

 

功能结果区别:

用法orjsonujsonrapidjson
序列化 orjson.dumps(data) → bytes ujson.dumps(data) → str rapidjson.dumps(data) → str
反序列化 orjson.loads(bytes/str) ujson.loads(str) rapidjson.loads(str)
注意点 返回 bytes,需 .decode() 无 datetime 支持 返回 str,兼容性强

 






功能特性orjsonujsonrapidjson
✅ 支持 datetime ✅ ISO 格式 ✅ 可配置格式
✅ 支持 Decimal ⚠️ 转为 float ✅ 原生支持
✅ 自定义对象序列化 ✅ 支持 default ✅ 支持 default
✅ 精度控制(float、NaN) ✅ option= 参数 ✅ 多选项支持
✅ 缩进与格式化输出 ✅(有) ✅ indent 参数
✅ 输出类型 bytes str str




 

 

 

  




4、json5

json5 是 JSON 的超集,允许更宽松的语法(如允许注释、单引号、不加引号的键等),适合人类书写配置文件。json5 库提供了对 JSON5 格式的解析支持。

pip install json5
import json5

# JSON5 字符串,包含注释、单引号、不加引号的键等
json5_str = """
{
    // 这是一个注释
    unquotedKey: 'value',
    "quotedKey": 123,
    trailingComma: true,
}
"""
# 解析 JSON5 字符串
data_loads = json5.loads(json5_str)
print(data_loads)

data_dumps = json5.dumps(json5_str)
print(data_dumps)

json5 库支持的扩展语法解析:

特性说明
注释 支持 // 单行注释 和 /* */ 多行注释
尾逗号 允许最后一个元素后写逗号
单引号字符串 'text' 与 "text" 都合法
未加引号的键 允许键名不加引号(如 foo: 1)
十六进制数字 支持 0x1234 数字表示
正负号数字 支持 +1、-2
多行字符串 可以使用 \ 跨行字符串
数字中的下划线 如 1_000_000(提高可读性)
 

  

  











写入 JSON5 数据
虽然 json5 支持读取 JSON5 文件,但并不支持将 Python 对象序列化为 JSON5 格式(即没有 json5.dumps() 带有 JSON5 特性的输出功能)。它只能写成标准 JSON


5、dataclasses_json

dtaclasses-json主要用于dataclasses 的 JSON 序列化/反序列化,它还支持dataclasses与dict类型的互相转化, 是 dataclasses 的一个强力补丁库。
pip install dataclasses-json

基本使用

from dataclasses import dataclass
from dataclasses_json import dataclass_json


@dataclass_json
@dataclass
class User:
    id: int
    name: str


user = User(id=1, name='Alice')

# 序列化为 JSON 字符串
json_str = user.to_json()
print(json_str)  # {"id": 1, "name": "Alice"}

# 反序列化为 Python 对象
new_user = User.from_json('{"id": 2, "name": "Bob"}')
print(new_user.name)  # Bob

# 转为字典
print(user.to_dict())  # {'id': 1, 'name': 'Alice'}

# 从字典创建
u = User.from_dict({'id': 3, 'name': 'Carol'})
print(u)  # User(id=3, name='Carol')

嵌套结构支持

from dataclasses import dataclass
from dataclasses_json import dataclass_json


@dataclass_json
@dataclass
class Address:
    city: str
    zipcode: str


@dataclass_json
@dataclass
class Person:
    name: str
    address: Address


p = Person(name='Tom', address=Address(city='NY', zipcode='10001'))

print(p.to_json())
# {"name": "Tom", "address": {"city": "NY", "zipcode": "10001"}}

# 自动反序列化嵌套结构
data = Person.from_json('{"name": "Amy", "address": {"city": "LA", "zipcode": "90001"}}')
print(data)
# Person(name='Amy', address=Address(city='LA', zipcode='90001'))

转换配置
config函数可以用于配置字段的类型和别名等。

from dataclasses import dataclass
from dataclasses_json import dataclass_json
import datetime


@dataclass_json
@dataclass
class Data:
    user_id: int = config(field_name='userId')
    time: datetime = config(
        encoder=datetime.isoformat,
        decoder=datetime.fromisoformat,
        mm_field=fields.DateTime()
    )

d = Data(user_id=1001, time=datetime(2024, 1, 1, 12, 0))

  

6、JSON数据校验

 6.1 jsonschema

jsonschema 是 Python 中用于JSON 数据结构验证的官方实现之一,遵循 JSON Schema 标准,可以验证 JSON 数据是否符合你定义的“规则/结构”。

pip install jsonschema

基本使用  

from jsonschema import validate
from jsonschema.exceptions import ValidationError

# 定义 JSON Schema(结构规则)
schema = {
    "type": "object",
    "properties": {
        "name":   {"type": "string"},
        "age":    {"type": "integer", "minimum": 0},
    },
    "required": ["name", "age"]
}

# 要校验的 JSON 数据
data = {
    "name": "Alice",
    "age": 30
}

try:
    validate({"name": "Bob"}, schema)
except ValidationError as e:
    print("校验失败:", e.message)

常见规则示例  

{
  "type": "object",
  "properties": {
    "username": {"type": "string", "minLength": 3, "pattern": "^[a-zA-Z0-9_]+$"},
    "age": {"type": "integer", "minimum": 0, "maximum": 120},
    "email": {"type": "string", "format": "email"},
    "tags": {
      "type": "array",
      "items": {"type": "string"},
      "maxItems": 5
    },
    "active": {"type": "boolean"}
  },
  "required": ["username", "email"]
}

自定义规则示例   

from jsonschema import Draft7Validator, FormatChecker

schema = {
    "type": "object",
    "properties": {
        "phone": {"type": "string", "format": "phone"}
    }
}


# 添加自定义格式检查器
@FormatChecker.cls_checks("phone")
def is_phone(value):
    import re
    return bool(re.match(r'^\d{11}$', value))


data = {"phone": "13800138000"}

 

 6.2  pydantic

Pydantic 是 Python 中最流行的数据验证和数据模型库,它的功能完全有必要另开一篇文章来详细讨论,这里仅仅介绍一下它在JSON 数据校验中的使用。

pip install pydantic

基本使用

from pydantic import Field

class Product(BaseModel):
    name: str = Field(..., min_length=3)
    price: float = Field(..., gt=0, lt=10000)

# 自动校验 JSON 字段
try:
    Product.model_validate({"name": "P", "price": -10})
except ValidationError as e:
    

数组与复杂结构

from typing import List

class Tag(BaseModel):
    name: str

class Post(BaseModel):
    title: str
    tags: List[Tag]

post_data = {
    "title": "My Post",
    "tags": [{"name": "Python"}, {"name": "FastAPI"}]
}

post = Post.model_validate(post_data)

自定义校验器  

from pydantic import field_validator

class User(BaseModel):
    username: str

    @field_validator('username')
    def no_spaces(cls, v):
        if ' ' in v:
            raise ValueError("username can't contain spaces")

  

 6.3  Voluptuous

Voluptuous 是一个用于 Python 数据校验的库,语法灵活、结构清晰,不同于jsonschema 所遵循JSON Schema 标准,它采用的是「函数式」「声明式」风格。

from voluptuous import Schema, Required, All, Length, Range, MultipleInvalid

schema = Schema({
    Required('name'): All(str, Length(min=2)),
    Required('age'): All(int, Range(min=0, max=120)),
    'email': str,
})

data = {
    'name': 'Alice',
    'age': 30,
    'email': 'alice@example.com'
}

try:
    schema({'name': 'A', 'age': -1})
except MultipleInvalid as e:
    print(e)

常用的构造器和校验器主要有: 

校验器功能
Required(...) 必须字段
Optional(...) 可选字段
All(...) 多重条件组合校验器
Length(min, max) 字符串或列表长度限制
Range(min, max) 数值范围限制
Match(r'^\w+$') 正则匹配
In([...]) 枚举(值必须属于其中之一)
Any(A, B) 多个类型之一
[type] 列表中每一项的类型
{str: int} 键值类型均为特定类型的 dict

 

 

  

  

  









嵌套结构与数组校验

config_schema = Schema({
    Required('host'): str,
    Required('port'): All(int, Range(min=1024, max=65535)),
    'debug': bool,
    'users': [{
        Required('name'): str,
        'email': str
    }]
})

config = {
    'host': 'localhost',
    'port': 8000,
    'debug': True,
    'users': [{'name': 'admin', 'email': 'admin@example.com'}]
}

自定义验证规则  

from voluptuous import Invalid


def is_even(v):
    if v % 2 != 0:
        raise Invalid("必须为偶数")
    return v


schema = Schema({'number': is_even})
print(schema({'number': 4}))

  

7、JSON数据的比较

7.1、jsondiff

jsondiff 是一个用于比较两个 JSON(或 Python 字典)对象差异的轻量级库。它能生成最小的变更(patch)表示,并支持将差异反向应用和还原原始数据。
pip install jsondiff

基本用法

import jsondiff

a = {"name": "Alice", "age": 30}
b = {"name": "Alice", "age": 31}

diff = jsondiff.diff(a, b)
print(diff)  # 输出:{'age': 31}

合并与还原(补丁 patch)  

import jsondiff

a = {"name": "Alice", "age": 30}
b = {"name": "Alice", "age": 31}

diff = jsondiff.diff(a, b)
print(diff)  # 输出:{'age': 31}

patch = jsondiff.diff(a, b)
new_obj = jsondiff.patch(a, patch)  # 应用 patch 得到 b
original = jsondiff.unpatch(new_obj, patch)  # 还原为 a

print(new_obj)  # {'name': 'Alice', 'age': 31}
print(original)  # {'name': 'Alice', 'age': 30}

嵌套结构 diff 

x = {"user": {"name": "Alice", "tags": ["a", "b"]}}
y = {"user": {"name": "Alice", "tags": ["a", "c"]}}

print(jsondiff.diff(x, y))

参数选项(比如忽略顺序)

a = {'numbers': [1, 2, 3]}
b = {'numbers': [3, 2, 1]}

# 默认考虑顺序
print(jsondiff.diff(a, b))  

# 忽略顺序
print(jsondiff.diff(a, b, dump=True, syntax='symmetric', sequence_matcher=jsondiff.SequenceMatcher))

7.2、deepdiff

比起jsondiff,deepdiff 的功能更加强大,尤其用于深度比较两个 Python 对象(特别是嵌套的 dict、list、set、tuple 等),并提供结构化的差异信息。

pip install deepdiff
from deepdiff import DeepDiff

a = {"name": "Alice", "age": 30}
b = {"name": "Alice", "age": 31}

diff = DeepDiff(a, b)
print(diff)

差异信息说明:  

键名含义
values_changed 值发生了变化
type_changes 类型发生变化
dictionary_item_added 新增键
dictionary_item_removed 删除键
iterable_item_added 列表/集合等新增项
iterable_item_removed 列表/集合等移除项
attribute_changed 对象属性变更(如类实例)

set_item_removed/set_item_added

集合元素变更

  

  

  

 








生成和应用补丁
from deepdiff import DeepDiff, patch, unpatch

a = {"x": 1}
b = {"x": 2}

ddiff = DeepDiff(a, b, view='tree')
p = ddiff.patch

# 应用 patch
new_data = patch(a, p)
print(new_data)  # {'x': 2}

# 还原
orig = unpatch(new_data, p)
print(orig ) 

差异路径与提取值

ddiff = DeepDiff(a, b, view='tree')
for diff_item in ddiff['values_changed']:
    print(diff_item.path(), diff_item.t1, "→", diff_item.t2)

嵌套结构 diff  

a = {"user": {"name": "Alice", "roles": ["admin", "dev"]}}
b = {"user": {"name": "Alice", "roles": ["admin", "ops"]}}

diff = DeepDiff(a, b)

参数选项(比如忽略顺序,设置精度)  

a = {'numbers': [1, 2, 3]}
b = {'numbers': [3, 2, 1]}

diff = DeepDiff(a, b, ignore_order=True)
print(diff)  # 无差异

# 浮点精度控制
diff = DeepDiff(0.3000000001, 0.3, significant_digits=7)

  

8、JSON数据的查询与操作

8.1  pyjq

pyjq 封装了 jq命令行工具,可以通过jq 表达式对 JSON 数据进行强大的模式匹配与提取、转换等操作。

pip install pyjq
import pyjq

data = {
    "users": [
        {"name": "Alice", "age": 30},
        {"name": "Bob", "age": 25}
    ]
}

result = pyjq.all('.users[] | select(.age > 26) | .name', data)

常用的jq 表达式:  

表达式含义
. 原始对象本身
.field 提取字段
.[] 遍历数组
select(.field > 10) 条件筛选
map(.field) 映射数组中每一项的某字段
.{a: .field1, b: .field2} 构造新字典
`.[] {name, age}`

  

 

 

 

 

 

 

  

 

嵌套结构

data = {
    "items": [
        {"id": 1, "tags": ["a", "b"]},
        {"id": 2, "tags": ["b", "c"]}
    ]
}

# 提取所有 tags
result = pyjq.all('.items[].tags[]', data)

提取字典转为新结构  

data = {
    "name": "Alice",
    "profile": {
        "email": "a@example.com",
        "phone": "123456"
    }
}

result = pyjq.first('{username: .name, contact: .profile.email}', data)

  

8.2  jsonpath-ng

jsonpath 是用于在 Python 中从 JSON 数据结构中提取数据的查询、操作工具,类似于 XPath 之于 XML。 jsonpath-ng(前身jsonpath)是 JSONPath 在 Python 中的主流实现库。

pip install jsonpath-ng

基本使用

from jsonpath_ng import jsonpath, parse

data = {
    "store": {
        "book": [
            {"title": "Book A", "price": 8.95},
            {"title": "Book B", "price": 12.99}
        ],
        "bicycle": {
            "color": "red",
            "price": 19.95
        }
    }
}

# 编译 JSONPath 表达式
jsonpath_expr = parse('$.store.book[*].title')

# 执行匹配并提取结果
matches = jsonpath_expr.find(data)
titles = [match.value for match in matches]

常见的JSONPath 表达式:

表达式说明
$ 根节点
$.store.book 访问键路径
$.store.book[*].title 遍历数组并提取字段
$..price 递归提取所有层级的 price
$.store.book[0] 第一个数组元素
$.store.book[-1:] 最后一个元素
$.store.book[?(@.price > 10)] 条件筛选

  

 

 

 

 

 

 

 

 

条件查询

expr = parse('$.store.book[?(@.price > 10)].title')
matches = expr.find(data)
titles = [m.value for m in matches]

修改数据
可以通过 match.path.update(data, new_value) 来修改原始数据:

expr = parse('$.store.bicycle.color')
matches = expr.find(data)

for match in matches:
    match.path.update(data, "blue")
print(data["store"]["bicycle"]["color"])  # blue

提取匹配路径和值  

for match in expr.find(data):
    print(match.path, match.value)

 

  

9、JSON数据文件的操作

9.1  ijson

ijson 是一个用于 增量解析 JSON 文件 的 Python 库,特别适用于 大文件/流式处理。它基于迭代器,可边读边解析,不会一次性加载整个 JSON,从而节省内存。

pip install ijson

基本用法

JSON数据源


{
  "records": {
    "item": [
      {"id": 1, "name": "Alice"},
      {"id": 2, "name": "Bob"}
    ]
  }
 }



import ijson

with open('large_file.json', 'r') as f:
    for item in ijson.items(f, 'records.item'):
        print(item)
# {'id': 1, 'name': 'Alice'}

读取嵌套数组结构

with open('large_file.json', 'r') as f:
    for item in ijson.items(f, 'data.users.item'):
      print(item)

从网络流/HTTP/Bytes 中读取

import requests
import ijson

response = requests.get('https://example.com/data.json', stream=True)
for item in ijson.items(response.raw, 'users.item'):
  print(item)

  

9.2   jsonlines

jsonlines 是一种特殊格式的 JSON 文件,每行是一个合法的 JSON 对象,广泛用于日志、数据流、大规模数据处理(如机器学习训练集) 中。

pip install jsonlines
JSON数据源

{"id": 1, "name": "Alice"}
{"id": 2, "name": "Bob"}



读取 JSON Lines 文件

import jsonlines

with jsonlines.open('data.jsonl') as reader:
    for obj in reader:
        print(obj['name'])

写入 JSON Lines 文件

import jsonlines

data = [{"id": 1}, {"id": 2}, {"id": 3}]
with jsonlines.open('output.jsonl', mode='w') as writer:
  writer.write_all(data)

  

9.3   jsonpickle

jsonpickle 是一个功能强大的 Python 库,用于将 复杂的 Python 对象(如自定义类、函数、日期、NumPy、Pandas 等)序列化为 JSON,并能将其反序列化回来,它支持更多内置类型与第三方类型。  

pip install jsonpickle

序列化(encode)

import jsonpickle

class Person:
    def __init__(self, name):
        self.name = name

obj = Person("Alice")

# 序列化为 JSON 字符串
json_str = jsonpickle.encode(obj)

反序列化(decode)  

obj_restored = jsonpickle.decode(json_str)

复杂类型

import jsonpickle
import datetime
import decimal

data = {
    "time": datetime.datetime.now(),
    "score": decimal.Decimal('9.99'),
    "tags": {"a", "b", "c"},
}

json_str = jsonpickle.encode(data)
print(json_str)

restored = jsonpickle.decode(json_str)

保存和加载 JSON 文件

# 写入文件
with open('person.json', 'w') as f:
    f.write(jsonpickle.encode(obj))

# 从文件读取
with open('person.json', 'r') as f:
  obj2 = jsonpickle.decode(f.read())

自定义 JSON处理库  

jsonpickle可以指定JSON的处理库,如选择高性能库orjson

import jsonpickle.ext.orjson as orjson
jsonpickle.set_encoder_options('orjson', option=orjson.OPT_INDENT_2)

  

posted @ 2025-07-02 10:42  北京测试菜鸟  阅读(93)  评论(0)    收藏  举报