Python中的JSON工具庫
1、原生json庫
json是Python內(nèi)置標(biāo)準(zhǔn)庫,開箱即用。json庫也非常簡單,就兩組序列化(編碼)、反序列化(解碼)方法。
基本使用
1)Python對(duì)象與JSON字符串的互相轉(zhuǎn)化:
import json
data = {"name": "Alice", "age": 30, "is_active": True}
# json.dumps將 Python 對(duì)象轉(zhuǎn)為 JSON 字符串
json_str = json.dumps(data)
print(json_str) # {"name": "Alice", "age": 30, "is_active": true}
# json.loads將JSON 字符串轉(zhuǎn)為 Python 對(duì)象
parsed = json.loads(json_str)
print(parsed) # {"name": "Alice", "age": 30, "is_active": true}
以下是Python 類型與JSON 類型的轉(zhuǎn)化對(duì)照,注意json 庫無法直接處理datetime, Decimal, UUID 等常用內(nèi)建類型以及自定義類對(duì)象。
| 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 文件時(shí)(如 GB 級(jí)),json.load() 會(huì)一次性讀取內(nèi)存,效率低甚至崩潰?!?/p>
具體參數(shù)說明:
| 參數(shù)名 | 說明 |
| indent=2 | 美化輸出(縮進(jìn)) |
| sort_keys=True | 字典按 key 排序輸出 |
| ensure_ascii=False | 輸出非 ASCII 字符(如中文) |
| default=function | 自定義無法序列化對(duì)象的處理方式 |
2、simplejson
simplejson 是 Python 的一個(gè)第三方 JSON 庫,是標(biāo)準(zhǔn)庫 json 的超集,提供更強(qiáng)大的功能與兼容性。它最初就是標(biāo)準(zhǔn)庫 json 的前身,所以用法非常相似,但提供了更多擴(kuò)展選項(xiàng)(如精度控制、Decimal 支持、自定義編碼等)
安裝
pip install simplejson
基本使用
simplejson也包含了loads\load,dumps\dump兩組序列化(編碼)、反序列化(解碼)方法,且使用方法與內(nèi)置的json庫一模一樣。
import simplejson as json
data = {"name": "Alice", "age": 30, "is_active": True}
# json.dumps將 Python 對(duì)象轉(zhuǎn)為 JSON 字符串
json_str = json.dumps(data)
print(json_str) # {"name": "Alice", "age": 30, "is_active": true}
# json.loads將JSON 字符串轉(zhuǎn)為 Python 對(duì)象
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(不會(huì)強(qiáng)制轉(zhuǎn) 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 對(duì)象轉(zhuǎn)為 JSON 字符串
json_str = orjson.dumps(data)
print(json_str) # b'{"name":"Alice","age":30,"is_active":true}'
# json.loads將JSON 字符串轉(zhuǎn)為 Python 對(duì)象
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 對(duì)象轉(zhuǎn)為 JSON 字符串
json_str = ujson.dumps(data)
print(json_str) # {"name":"Alice","age":30,"is_active":true}
# json.loads將JSON 字符串轉(zhuǎn)為 Python 對(duì)象
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 對(duì)象轉(zhuǎn)為 JSON 字符串
json_str = rapidjson.dumps(data)
print(json_str) # {"name":"Alice","age":30,"is_active":true}
# json.loads將JSON 字符串轉(zhuǎn)為 Python 對(duì)象
parsed = rapidjson.loads(json_str)
print(parsed) # {'name': 'Alice', 'age': 30, 'is_active': True}
orjson、ujson、rapidjson與json區(qū)別:
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)
性能結(jié)果區(qū)別:
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 時(shí)間 | loads 時(shí)間 | 總體性能評(píng)價(jià) |
|---|---|---|---|
| orjson | ?? 最快(~0.09s) | ?? 最快(~0.08s) | ?????? 超高速 |
| ujson | 次快(~0.13s) | 次快(~0.12s) | ???? 快 |
| rapidjson | 稍慢(~0.18s) | 穩(wěn)定(~0.15s) | ?? 中等 |
| json(內(nèi)置) | ?? ~0.27s | ?? ~0.23s | ?? 慢 |
功能結(jié)果區(qū)別:
| 用法 | orjson | ujson | rapidjson |
|---|---|---|---|
| 序列化 | orjson.dumps(data) → bytes | ujson.dumps(data) → str | rapidjson.dumps(data) → str |
| 反序列化 | orjson.loads(bytes/str) | ujson.loads(str) | rapidjson.loads(str) |
| 注意點(diǎn) | 返回 bytes,需 .decode() | 無 datetime 支持 | 返回 str,兼容性強(qiáng) |
| 功能特性 | orjson | ujson | rapidjson |
|---|---|---|---|
| ? 支持 datetime | ? ISO 格式 | ? | ? 可配置格式 |
| ? 支持 Decimal | ?? 轉(zhuǎn)為 float | ? | ? 原生支持 |
| ? 自定義對(duì)象序列化 | ? 支持 default | ? | ? 支持 default |
| ? 精度控制(float、NaN) | ? option= 參數(shù) | ? | ? 多選項(xiàng)支持 |
| ? 縮進(jìn)與格式化輸出 | ?(有) | ? | ? indent 參數(shù) |
| ? 輸出類型 | bytes | str | str |
4、json5
json5 是 JSON 的超集,允許更寬松的語法(如允許注釋、單引號(hào)、不加引號(hào)的鍵等),適合人類書寫配置文件。json5 庫提供了對(duì) JSON5 格式的解析支持。
pip install json5
import json5
# JSON5 字符串,包含注釋、單引號(hào)、不加引號(hào)的鍵等
json5_str = """
{
// 這是一個(gè)注釋
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 庫支持的擴(kuò)展語法解析:
| 特性 | 說明 |
|---|---|
| 注釋 | 支持 // 單行注釋 和 /* */ 多行注釋 |
| 尾逗號(hào) | 允許最后一個(gè)元素后寫逗號(hào) |
| 單引號(hào)字符串 | 'text' 與 "text" 都合法 |
| 未加引號(hào)的鍵 | 允許鍵名不加引號(hào)(如 foo: 1) |
| 十六進(jìn)制數(shù)字 | 支持 0x1234 數(shù)字表示 |
| 正負(fù)號(hào)數(shù)字 | 支持 +1、-2 |
| 多行字符串 | 可以使用 \ 跨行字符串 |
| 數(shù)字中的下劃線 | 如 1_000_000(提高可讀性)
|
寫入 JSON5 數(shù)據(jù)
雖然 json5 支持讀取 JSON5 文件,但并不支持將 Python 對(duì)象序列化為 JSON5 格式(即沒有 json5.dumps() 帶有 JSON5 特性的輸出功能)。它只能寫成標(biāo)準(zhǔn) JSON
5、dataclasses_json
dtaclasses-json主要用于dataclasses 的 JSON 序列化/反序列化,它還支持dataclasses與dict類型的互相轉(zhuǎn)化, 是 dataclasses 的一個(gè)強(qiáng)力補(bǔ)丁庫。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 對(duì)象
new_user = User.from_json('{"id": 2, "name": "Bob"}')
print(new_user.name) # Bob
# 轉(zhuǎn)為字典
print(user.to_dict()) # {'id': 1, 'name': 'Alice'}
# 從字典創(chuàng)建
u = User.from_dict({'id': 3, 'name': 'Carol'})
print(u) # User(id=3, name='Carol')
嵌套結(jié)構(gòu)支持
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"}}
# 自動(dòng)反序列化嵌套結(jié)構(gòu)
data = Person.from_json('{"name": "Amy", "address": {"city": "LA", "zipcode": "90001"}}')
print(data)
# Person(name='Amy', address=Address(city='LA', zipcode='90001'))
轉(zhuǎn)換配置config函數(shù)可以用于配置字段的類型和別名等。
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數(shù)據(jù)校驗(yàn)
6.1 jsonschema
jsonschema 是 Python 中用于JSON 數(shù)據(jù)結(jié)構(gòu)驗(yàn)證的官方實(shí)現(xiàn)之一,遵循 JSON Schema 標(biāo)準(zhǔn),可以驗(yàn)證 JSON 數(shù)據(jù)是否符合你定義的“規(guī)則/結(jié)構(gòu)”。
pip install jsonschema
基本使用
from jsonschema import validate
from jsonschema.exceptions import ValidationError
# 定義 JSON Schema(結(jié)構(gòu)規(guī)則)
schema = {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer", "minimum": 0},
},
"required": ["name", "age"]
}
# 要校驗(yàn)的 JSON 數(shù)據(jù)
data = {
"name": "Alice",
"age": 30
}
try:
validate({"name": "Bob"}, schema)
except ValidationError as e:
print("校驗(yàn)失敗:", e.message)
常見規(guī)則示例
{
"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"]
}
自定義規(guī)則示例
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 中最流行的數(shù)據(jù)驗(yàn)證和數(shù)據(jù)模型庫,它的功能完全有必要另開一篇文章來詳細(xì)討論,這里僅僅介紹一下它在JSON 數(shù)據(jù)校驗(yàn)中的使用。
pip install pydantic
基本使用
from pydantic import Field
class Product(BaseModel):
name: str = Field(..., min_length=3)
price: float = Field(..., gt=0, lt=10000)
# 自動(dòng)校驗(yàn) JSON 字段
try:
Product.model_validate({"name": "P", "price": -10})
except ValidationError as e:
數(shù)組與復(fù)雜結(jié)構(gòu)
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)
自定義校驗(yàn)器
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 是一個(gè)用于 Python 數(shù)據(jù)校驗(yàn)的庫,語法靈活、結(jié)構(gòu)清晰,不同于jsonschema 所遵循JSON Schema 標(biāo)準(zhǔn),它采用的是「函數(shù)式」「聲明式」風(fēng)格。
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)
常用的構(gòu)造器和校驗(yàn)器主要有:
| 校驗(yàn)器 | 功能 |
|---|---|
| Required(...) | 必須字段 |
| Optional(...) | 可選字段 |
| All(...) | 多重條件組合校驗(yàn)器 |
| Length(min, max) | 字符串或列表長度限制 |
| Range(min, max) | 數(shù)值范圍限制 |
| Match(r'^\w+$') | 正則匹配 |
| In([...]) | 枚舉(值必須屬于其中之一) |
| Any(A, B) | 多個(gè)類型之一 |
| [type] | 列表中每一項(xiàng)的類型 |
| {str: int} | 鍵值類型均為特定類型的 dict |
嵌套結(jié)構(gòu)與數(shù)組校驗(yàn)
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'}]
}
自定義驗(yàn)證規(guī)則
from voluptuous import Invalid
def is_even(v):
if v % 2 != 0:
raise Invalid("必須為偶數(shù)")
return v
schema = Schema({'number': is_even})
print(schema({'number': 4}))
7、JSON數(shù)據(jù)的比較
7.1、jsondiff
jsondiff 是一個(gè)用于比較兩個(gè) JSON(或 Python 字典)對(duì)象差異的輕量級(jí)庫。它能生成最小的變更(patch)表示,并支持將差異反向應(yīng)用和還原原始數(shù)據(jù)。pip install jsondiff
基本用法
import jsondiff
a = {"name": "Alice", "age": 30}
b = {"name": "Alice", "age": 31}
diff = jsondiff.diff(a, b)
print(diff) # 輸出:{'age': 31}
合并與還原(補(bǔ)丁 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) # 應(yīng)用 patch 得到 b
original = jsondiff.unpatch(new_obj, patch) # 還原為 a
print(new_obj) # {'name': 'Alice', 'age': 31}
print(original) # {'name': 'Alice', 'age': 30}
嵌套結(jié)構(gòu) diff
x = {"user": {"name": "Alice", "tags": ["a", "b"]}}
y = {"user": {"name": "Alice", "tags": ["a", "c"]}}
print(jsondiff.diff(x, y))
參數(shù)選項(xiàng)(比如忽略順序)
a = {'numbers': [1, 2, 3]}
b = {'numbers': [3, 2, 1]}
# 默認(rèn)考慮順序
print(jsondiff.diff(a, b))
# 忽略順序
print(jsondiff.diff(a, b, dump=True, syntax='symmetric', sequence_matcher=jsondiff.SequenceMatcher))
7.2、deepdiff
比起jsondiff,deepdiff 的功能更加強(qiáng)大,尤其用于深度比較兩個(gè) Python 對(duì)象(特別是嵌套的 dict、list、set、tuple 等),并提供結(jié)構(gòu)化的差異信息。
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 | 值發(fā)生了變化 |
| type_changes | 類型發(fā)生變化 |
| dictionary_item_added | 新增鍵 |
| dictionary_item_removed | 刪除鍵 |
| iterable_item_added | 列表/集合等新增項(xiàng) |
| iterable_item_removed | 列表/集合等移除項(xiàng) |
| attribute_changed | 對(duì)象屬性變更(如類實(shí)例) |
|
set_item_removed/set_item_added |
集合元素變更 |
生成和應(yīng)用補(bǔ)丁
from deepdiff import DeepDiff, patch, unpatch
a = {"x": 1}
b = {"x": 2}
ddiff = DeepDiff(a, b, view='tree')
p = ddiff.patch
# 應(yīng)用 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)
嵌套結(jié)構(gòu) diff
a = {"user": {"name": "Alice", "roles": ["admin", "dev"]}}
b = {"user": {"name": "Alice", "roles": ["admin", "ops"]}}
diff = DeepDiff(a, b)
參數(shù)選項(xiàng)(比如忽略順序,設(shè)置精度)
a = {'numbers': [1, 2, 3]}
b = {'numbers': [3, 2, 1]}
diff = DeepDiff(a, b, ignore_order=True)
print(diff) # 無差異
# 浮點(diǎn)精度控制
diff = DeepDiff(0.3000000001, 0.3, significant_digits=7)
8、JSON數(shù)據(jù)的查詢與操作
8.1 pyjq
pyjq 封裝了 jq命令行工具,可以通過jq 表達(dá)式對(duì) JSON 數(shù)據(jù)進(jìn)行強(qiáng)大的模式匹配與提取、轉(zhuǎn)換等操作。
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 表達(dá)式:
| 表達(dá)式 | 含義 |
|---|---|
| . | 原始對(duì)象本身 |
| .field | 提取字段 |
| .[] | 遍歷數(shù)組 |
| select(.field > 10) | 條件篩選 |
| map(.field) | 映射數(shù)組中每一項(xiàng)的某字段 |
| .{a: .field1, b: .field2} | 構(gòu)造新字典 |
| `.[] | {name, age}` |
嵌套結(jié)構(gòu)
data = {
"items": [
{"id": 1, "tags": ["a", "b"]},
{"id": 2, "tags": ["b", "c"]}
]
}
# 提取所有 tags
result = pyjq.all('.items[].tags[]', data)
提取字典轉(zhuǎn)為新結(jié)構(gòu)
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 數(shù)據(jù)結(jié)構(gòu)中提取數(shù)據(jù)的查詢、操作工具,類似于 XPath 之于 XML。 jsonpath-ng(前身jsonpath)是 JSONPath 在 Python 中的主流實(shí)現(xiàn)庫。
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 表達(dá)式
jsonpath_expr = parse('$.store.book[*].title')
# 執(zhí)行匹配并提取結(jié)果
matches = jsonpath_expr.find(data)
titles = [match.value for match in matches]
常見的JSONPath 表達(dá)式:
| 表達(dá)式 | 說明 |
|---|---|
| $ | 根節(jié)點(diǎn) |
| $.store.book | 訪問鍵路徑 |
| $.store.book[*].title | 遍歷數(shù)組并提取字段 |
| $..price | 遞歸提取所有層級(jí)的 price |
| $.store.book[0] | 第一個(gè)數(shù)組元素 |
| $.store.book[-1:] | 最后一個(gè)元素 |
| $.store.book[?(@.price > 10)] | 條件篩選 |
條件查詢
expr = parse('$.store.book[?(@.price > 10)].title')
matches = expr.find(data)
titles = [m.value for m in matches]
修改數(shù)據(jù)
可以通過 match.path.update(data, new_value) 來修改原始數(shù)據(jù):
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數(shù)據(jù)文件的操作
9.1 ijson
ijson 是一個(gè)用于 增量解析 JSON 文件 的 Python 庫,特別適用于 大文件/流式處理。它基于迭代器,可邊讀邊解析,不會(huì)一次性加載整個(gè) JSON,從而節(jié)省內(nèi)存。
pip install ijson
基本用法
JSON數(shù)據(jù)源
{
"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'}
讀取嵌套數(shù)組結(jié)構(gòu)
with open('large_file.json', 'r') as f:
for item in ijson.items(f, 'data.users.item'):
print(item)
從網(wǎng)絡(luò)流/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 文件,每行是一個(gè)合法的 JSON 對(duì)象,廣泛用于日志、數(shù)據(jù)流、大規(guī)模數(shù)據(jù)處理(如機(jī)器學(xué)習(xí)訓(xùn)練集) 中。
pip install jsonlines
JSON數(shù)據(jù)源
{"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 是一個(gè)功能強(qiáng)大的 Python 庫,用于將 復(fù)雜的 Python 對(duì)象(如自定義類、函數(shù)、日期、NumPy、Pandas 等)序列化為 JSON,并能將其反序列化回來,它支持更多內(nèi)置類型與第三方類型。
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)
復(fù)雜類型
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)

浙公網(wǎng)安備 33010602011771號(hào)