Python3 JSON
Serialising to and from JSON, handling datetime and Decimal, and when to use csv or pickle.
Key Points`ensure_ascii=False` keeps Chinese readable; datetime and Decimal need an explicit default= encoder.
dumps / loads
Python
import json
data = {"id": 1, "name": "后端", "tags": ["api", "py"]}
text = json.dumps(data, ensure_ascii=False, indent=2)
print(text)
# {
# "id": 1,
# "name": "后端",
# "tags": ["api", "py"]
# }
back = json.loads(text)
print(back["name"]) # 后端| Function | Direction | Target |
|---|---|---|
| json.dumps(obj) | Python -> str | String |
| json.loads(s) | str -> Python | Object |
| json.dump(obj, f) | Python -> file | File object |
| json.load(f) | file -> Python | Object |
Non-serialisable Types
datetime, Decimal, set and custom objects are not JSON types. Provide default= for encoding and object_hook/parse_float for decoding.
Python
import json
from datetime import datetime, date
from decimal import Decimal
def encode(o):
if isinstance(o, (datetime, date)):
return o.isoformat()
if isinstance(o, Decimal):
return str(o) # 金额用字符串,避免精度丢失
if isinstance(o, set):
return sorted(o)
raise TypeError(f"not JSON serialisable: {type(o)}")
payload = {"at": datetime(2026, 1, 1, 12, 0), "price": Decimal("19.90")}
print(json.dumps(payload, default=encode, ensure_ascii=False))
# {"at": "2026-01-01T12:00:00", "price": "19.90"}csv
Python
import csv
with open("users.csv", encoding="utf-8", newline="") as f:
for row in csv.DictReader(f): # 按表头映射成字典
print(row["name"], row["age"])
with open("out.csv", "w", encoding="utf-8", newline="") as f:
w = csv.DictWriter(f, fieldnames=["name", "age"])
w.writeheader()
w.writerows([{"name": "alice", "age": 30}])pickle
pickle serialises arbitrary Python objects, but it is not safe to load untrusted data — unpickling can execute code. Use it for local caches only.
Python
import pickle
blob = pickle.dumps({"a": 1})
pickle.loads(blob) # {'a': 1}
# 跨语言 / 跨版本 / 公开接口:用 JSONjson.dumps with ensure_ascii=True (the default) turns 后端 into \u540e\u7aef. Always pass ensure_ascii=False for Chinese content.dumps 与 loads
Python
import json
data = {"id": 1, "name": "后端", "tags": ["api", "py"]}
text = json.dumps(data, ensure_ascii=False, indent=2)
print(text)
# {
# "id": 1,
# "name": "后端",
# "tags": ["api", "py"]
# }
back = json.loads(text)
print(back["name"]) # 后端| 函数 | 方向 | 目标 |
|---|---|---|
| json.dumps(obj) | Python → 字符串 | 字符串 |
| json.loads(s) | 字符串 → Python | 对象 |
| json.dump(obj, f) | Python → 文件 | 文件对象 |
| json.load(f) | 文件 → Python | 对象 |
不能直接序列化的类型
datetime、Decimal、set 和自定义对象都不是 JSON 类型。编码时给 default=,解码时用 object_hook/parse_float。
Python
import json
from datetime import datetime, date
from decimal import Decimal
def encode(o):
if isinstance(o, (datetime, date)):
return o.isoformat()
if isinstance(o, Decimal):
return str(o) # 金额用字符串,避免精度丢失
if isinstance(o, set):
return sorted(o)
raise TypeError(f"not JSON serialisable: {type(o)}")
payload = {"at": datetime(2026, 1, 1, 12, 0), "price": Decimal("19.90")}
print(json.dumps(payload, default=encode, ensure_ascii=False))
# {"at": "2026-01-01T12:00:00", "price": "19.90"}csv
Python
import csv
with open("users.csv", encoding="utf-8", newline="") as f:
for row in csv.DictReader(f): # 按表头映射成字典
print(row["name"], row["age"])
with open("out.csv", "w", encoding="utf-8", newline="") as f:
w = csv.DictWriter(f, fieldnames=["name", "age"])
w.writeheader()
w.writerows([{"name": "alice", "age": 30}])pickle
pickle 能序列化任意 Python 对象,但不能加载不可信数据 —— 反序列化可以执行任意代码。只用于本地缓存。
Python
import pickle
blob = pickle.dumps({"a": 1})
pickle.loads(blob) # {'a': 1}
# 跨语言 / 跨版本 / 公开接口:用 JSONjson.dumps 默认 ensure_ascii=True,会把「后端」变成 \u540e\u7aef。中文内容务必传 ensure_ascii=False。