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"])  # 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

高级用法

当数据结构中包含 datetimeDecimal 或自定义类实例时,直接序列化会抛出 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 结合处理流式数据)?欢迎在评论区分享你的故事,让我们一起把轻量级数据交换玩出深度!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值