json模块
json 模块处理 JSON(JavaScript Object Notation)数据的编码和解码。JSON 是 Web 开发中最常用的数据交换格式,Python 的 json 模块让 Python 对象与 JSON 字符串之间的转换变得简单直接。
编码:Python → JSON
json.dumps:Python 对象 → JSON 字符串
import json
data = {
"name": "Alice",
"age": 30,
"is_student": False,
"courses": ["Math", "Physics"],
"address": None
}
json_str = json.dumps(data)
print json_str
# {"name": "Alice", "age": 30, "is_student": false, "courses": ["Math", "Physics"], "address": null}
注意 JSON 与 Python 的类型差异:
| Python | JSON |
|---|---|
| dict | object |
| list, tuple | array |
| str, unicode | string |
| int, long, float | number |
| True | true |
| False | false |
| None | null |
格式化输出:
print json.dumps(data, indent=2, ensure_ascii=False)
# {
# "name": "Alice",
# "age": 30,
# "is_student": false,
# "courses": [
# "Math",
# "Physics"
# ],
# "address": null
# }
indent 控制缩进,ensure_ascii=False 允许非 ASCII 字符直接输出(如中文)。
排序键:
print json.dumps(data, sort_keys=True)
# {"address": null, "age": 30, "courses": ["Math", "Physics"], "is_student": false, "name": "Alice"}
解码:JSON → Python
json.loads:JSON 字符串 → Python 对象
import json
json_str = '{"name": "Bob", "age": 25}'
data = json.loads(json_str)
print data # {u'name': u'Bob', u'age': 25}
print type(data) # <type 'dict'>
print data["name"] # Bob
Python 2 中 JSON 字符串解码为 unicode 类型,而非 str。
从文件读取:
import json
with open("data.json", "r") as f:
data = json.load(f)
print data
写入文件:
import json
data = {"users": [{"name": "Alice"}, {"name": "Bob"}]}
with open("data.json", "w") as f:
json.dump(data, f, indent=2)
处理自定义类型
JSON 默认不支持 Python 的 datetime、set 等类型:
import json
from datetime import datetime
data = {"time": datetime.now()}
# json.dumps(data) # TypeError: datetime is not JSON serializable
自定义编码器:
import json
from datetime import datetime
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.strftime("%Y-%m-%d %H:%M:%S")
return super(CustomEncoder, self).default(obj)
data = {"time": datetime.now()}
print json.dumps(data, cls=CustomEncoder)
# {"time": "2024-01-15 14:30:25"}
自定义解码器:
import json
from datetime import datetime
def datetime_decoder(d):
if "time" in d:
d["time"] = datetime.strptime(d["time"], "%Y-%m-%d %H:%M:%S")
return d
json_str = '{"time": "2024-01-15 14:30:25"}'
data = json.loads(json_str, object_hook=datetime_decoder)
print type(data["time"]) # <type 'datetime.datetime'>
实际应用
配置文件:
import json
def load_config(filename="config.json"):
try:
with open(filename, "r") as f:
return json.load(f)
except (IOError, ValueError):
return {}
def save_config(config, filename="config.json"):
with open(filename, "w") as f:
json.dump(config, f, indent=2)
# 使用
config = load_config()
config["theme"] = "dark"
save_config(config)
API 响应处理:
import json
import urllib2
response = urllib2.urlopen("https://api.example.com/users")
data = json.load(response)
for user in data["users"]:
print user["name"], user["email"]
数据缓存:
import json
import os
def cache_result(key, data, cache_dir="cache"):
if not os.path.exists(cache_dir):
os.makedirs(cache_dir)
path = os.path.join(cache_dir, key + ".json")
with open(path, "w") as f:
json.dump(data, f)
def load_cache(key, cache_dir="cache"):
path = os.path.join(cache_dir, key + ".json")
if os.path.exists(path):
with open(path, "r") as f:
return json.load(f)
return None
与 pickle 的区别
| 特性 | json | pickle |
|---|---|---|
| 格式 | 文本,人类可读 | 二进制 |
| 跨语言 | 是 | 否(仅 Python) |
| 安全性 | 安全 | 不安全(不要加载不可信数据) |
| 支持类型 | 基本类型 | 几乎所有 Python 对象 |
| 性能 | 较慢 | 较快 |
import json
import pickle
data = {"key": "value"}
# JSON:文本格式
print json.dumps(data) # {"key": "value"}
# Pickle:二进制格式
print pickle.dumps(data) # 不可读的二进制数据
Web 开发、配置文件、API 交互用 json。Python 对象持久化、进程间通信用 pickle(注意安全性)。