orjson 基础教程
orjson 是目前 Python最快的 JSON 库(基于 Rust 实现),特点:
- 序列化(dumps)速度 10–20 倍于内置 json
- 反序列化(loads)速度 5–10 倍
- 内置支持:
- datetime
- date
- uuid.UUID
- numpy
- dataclass
- 自动输出 UTF-8,不需要 ensure_ascii=False
- dumps 输出 bytes(不是 str)
安装:
pip install orjson
import orjson
data = orjson.loads(b'{"a": 1, "b": 2}')
print(data) # {'a': 1, 'b': 2}
注意:orjson 接受 bytes 或 str。
import orjson
s = orjson.dumps({"name": "martin"})
print(s) # b'{"name":"martin"}'
print(s.decode()) # {"name":"martin"}
关键差别:
- ✅ 返回值永远是 bytes
- ❌ 不返回 str(这是 orjson 的特点)
orjson.dumps(data, option=orjson.OPT_INDENT_2)
orjson.dumps(data, option=orjson.OPT_SORT_KEYS)
orjson.dumps({1: "a"}, option=orjson.OPT_NON_STR_KEYS)
# b'{"1":"a"}'
from datetime import datetime, timezone
now = datetime.now(timezone.utc)
orjson.dumps({"time": now})
# b'{"time":"2025-02-16T08:25:41.222Z"}'
orjson 默认支持:
- datetime
- date
- time
- timedelta
- uuid.UUID
内置 json 是不支持的。
注意用 |:
orjson.dumps(
data,
option=orjson.OPT_INDENT_2 | orjson.OPT_SORT_KEYS
)
相当于 json.dumps(... default=fn)。
例:支持 Decimal:
import orjson
from decimal import Decimal
def default(obj):
if isinstance(obj, Decimal):
return float(obj)
raise TypeError
data = {"amount": Decimal("12.34")}
print(orjson.dumps(data, default=default))
| Python 类型 | json | orjson |
|---|---|---|
| set | ❌ | ❌ |
| complex | ❌ | ❌ |
| bytes | ❌ | ❌(不会自动 decode) |
| datetime | ❌ | ✅ |
| Decimal | ❌ | ❌(需要 default) |
若遇到错误:
TypeError: Type is not JSON serializable
你必须用 default:
orjson.dumps(obj, default=lambda o: str(o))
| 功能 | json | orjson |
|---|---|---|
| 序列化速度 | 普通 | 最快(Rust) |
| 反序列化速度 | 普通 | 更快 |
| datetime 自动支持 | ❌ | ✅ |
| unicode 输出 | 默认转 \uXXXX | 默认 UTF-8 |
| 返回 str | ✅ | ❌(返回 bytes) |
| 美化输出 | indent | option |
你可以让整个 FastAPI 自动使用 orjson 替代 json:
from fastapi import FastAPI
from fastapi.responses import ORJSONResponse
app = FastAPI(default_response_class=ORJSONResponse)
整个接口输出速度提升明显。
非常建议直接封装:
# utils/json.py
import orjson
from decimal import Decimal
from datetime import datetime, date
def default(obj):
if isinstance(obj, (datetime, date)):
return obj.isoformat()
if isinstance(obj, Decimal):
return float(obj)
return str(obj)
def dumps(data, **kwargs) -> str:
return orjson.dumps(data, default=default, **kwargs).decode()
使用:
from utils.json import dumps
print(dumps({"time": datetime.now()}))
orjson.dumps()返回 bytes,需要.decode()- 内置支持 datetime/date/uuid,不需要 default
- 美化输出:OPT_INDENT_2
- 合并 option 用 |
- 性能比 json 快一大截
- FastAPI 可以直接用 ORJSONResponse