json,一个通用的 Python 库!
【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"]) # dark4. 将 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结合处理流式数据)?欢迎在评论区分享你的故事,让我们一起把轻量级数据交换玩出深度!
