【json,一个通用的 Python 库!】
在当今的数字化生活中,数据交换无处不在。无论是你手机上的天气应用从云端拉取实时预报,还是你在电商网站下单后订单系统与仓储系统之间的信息同步,背后都离不开一种轻量、易读且跨语言的数据格式——JSON(JavaScript Object Notation)。而 Python 内置的 json 标准库,正是我们处理这种格式最锋利、最可靠的瑞士军刀。
想象一下:你写了一个自动化脚本,每天爬取股市收盘价,需要保存到本地供第二天分析;或者你开发了一款桌面便签工具,希望用户的笔记能导出为可移植的文件;又或者你需要调用 ChatGPT 的 API,发送复杂的提示词并解析返回的结构化结果。所有这些场景中,json 库都能用寥寥几行代码,将 Python 的字典、列表等原生对象与 JSON 字符串或文件无缝互转。它让“配置持久化”、“API 通信”、“数据日志”变得像呼吸一样自然。
安装库
令人愉悦的是,json 是 Python 的标准库,自 Python 2.5 起便内置在解释器中。你无需执行任何 pip install 操作,只需在代码中直接导入即可:
python
import json
如果你使用的是某些精简版环境(如嵌入式 Python),理论上标准库依然存在。放心,它永远在那里等你。
基本用法
我们通过四个渐进步骤掌握 json 的核心能力。
1. 将 Python 对象序列化为 JSON 字符串
python
data = {
"name": "Alice",
"age": 30,
"skills": ["Python", "JSON"],
"is_active": True
}
json_str = json.dumps(data, indent=2) # indent 让输出更美观
print(json_str)
输出:
json
{
"name": "Alice",
"age": 30,
"skills": ["Python", "JSON"],
"is_active": true
}
2. 将 JSON 字符串反序列化为 Python 对象
python
original = json.loads(json_str) print(original["skills"][0]) # 输出: Python
3. 直接从文件读取 JSON
假设有一个 config.json 文件:
json
{"theme": "dark", "font_size": 14}
读取代码:
python
with open("config.json", "r", encoding="utf-8") as f:
config = json.load(f)
print(config["theme"]) # dark
4. 将 Python 对象写入 JSON 文件
python
user_profile = {"username": "bob", "points": 1270}
with open("profile.json", "w", encoding="utf-8") as f:
json.dump(user_profile, f, indent=2, ensure_ascii=False)
ensure_ascii=False 允许写入中文等非 ASCII 字符,否则它们会被转义为 \uXXXX。
高级用法
当数据结构中包含 datetime、Decimal 或自定义类实例时,直接序列化会抛出 TypeError。此时你需要自定义编码器。
自定义 JSON 编码器处理日期和时间
python
from datetime import datetime, date
import json
class CustomEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime):
return obj.isoformat()
if isinstance(obj, date):
return obj.isoformat()
# 让父类处理其他未知类型
return super().default(obj)
data = {"event": "meeting", "time": datetime.now()}
json_str = json.dumps(data, cls=CustomEncoder, indent=2)
print(json_str)
使用 object_hook 解码时自动重建对象
当你读取包含 ISO 日期字符串的 JSON 时,可以将其自动转回 datetime:
python
def decode_dates(dict_obj):
for key, value in dict_obj.items():
if key == "time" and isinstance(value, str):
try:
dict_obj[key] = datetime.fromisoformat(value)
except:
pass
return dict_obj
with open("schedule.json", "r") as f:
loaded = json.load(f, object_hook=decode_dates)
print(type(loaded["time"])) # <class 'datetime.datetime'>
实际应用场景
场景一:本地待办事项管理工具(深度案例)
日常生活中,我们经常需要一个轻量级的 CLI 待办清单,数据存在本地 todo.json 文件中。下面是一个完整可运行的示例,包含添加、列出、完成标记功能:
python
import json
import os
from datetime import datetime
TODO_FILE = "todo.json"
def load_tasks():
if not os.path.exists(TODO_FILE):
return []
with open(TODO_FILE, "r", encoding="utf-8") as f:
return json.load(f)
def save_tasks(tasks):
with open(TODO_FILE, "w", encoding="utf-8") as f:
json.dump(tasks, f, indent=2, ensure_ascii=False)
def add_task(description):
tasks = load_tasks()
new_id = max([t["id"] for t in tasks], default=0) + 1
tasks.append({
"id": new_id,
"description": description,
"completed": False,
"created_at": datetime.now().isoformat()
})
save_tasks(tasks)
print(f"✅ 任务 {new_id} 已添加")
def list_tasks():
tasks = load_tasks()
if not tasks:
print("暂无任务")
return
for t in tasks:
status = "✔" if t["completed"] else "❌"
print(f"[{status}] {t['id']}: {t['description']} (创建于 {t['created_at']})")
def complete_task(task_id):
tasks = load_tasks()
for t in tasks:
if t["id"] == task_id:
t["completed"] = True
save_tasks(tasks)
print(f"🎉 任务 {task_id} 已完成")
return
print(f"未找到任务 {task_id}")
if __name__ == "__main__":
# 简单演示
add_task("学习 json 库的高级用法")
add_task("写一篇技术文章")
list_tasks()
complete_task(1)
list_tasks()
场景二:缓存 API 请求结果
很多个人脚本频繁调用免费天气 API,容易被限流。使用 JSON 缓存最近 1 小时的结果:
python
import json
import time
import requests
from functools import wraps
CACHE_FILE = "api_cache.json"
def cached_api(expire_seconds=3600):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
# 加载已有缓存
try:
with open(CACHE_FILE, "r") as f:
cache = json.load(f)
except (FileNotFoundError, json.JSONDecodeError):
cache = {}
key = f"{func.__name__}_{args}_{kwargs}"
now = time.time()
if key in cache and now - cache[key]["timestamp"] < expire_seconds:
print("从缓存返回数据")
return cache[key]["data"]
# 调用真实 API
result = func(*args, **kwargs)
cache[key] = {"data": result, "timestamp": now}
with open(CACHE_FILE, "w") as f:
json.dump(cache, f, indent=2)
return result
return wrapper
return decorator
@cached_api(expire_seconds=600)
def get_weather(city):
# 示例:实际应替换为真实 API
return {"city": city, "temp": 22, "condition": "sunny"}
# 第一次调用会请求,第二次 10 分钟内直接从缓存读取
print(get_weather("Beijing"))
print(get_weather("Beijing"))
总结与互动
JSON 作为事实上的数据交换语言,配合 Python 的 json 库,让开发者能用近乎直觉的方式完成配置管理、本地存储、API 对接等日常工作。从最简单的 dumps/loads 到自定义编码器和缓存系统,它始终保持着“够用且不复杂”的优雅姿态。掌握 json,你就能打通 Python 与外部世界的文本数据管道,让脚本真正融入你的数字化生活。
现在,我想问问你:你在哪个实际项目中因为 JSON 格式不统一或编码错误而踩过坑?或者你是否有更巧妙的 json 使用技巧(比如与 itertools 结合处理流式数据)?欢迎在评论区分享你的故事,让我们一起把轻量级数据交换玩出深度!
1925

被折叠的 条评论
为什么被折叠?



