飞翔飞翔
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
  • 学习路径
  • 第1章 认识Python

    • Python 历史与特点
    • Python 2 与 Python 3 的核心差异
    • 安装与运行 Python 2.7.18
    • 编码规范 PEP 8
  • 第2章 基础语法

    • 变量与对象
    • 数字类型
    • 字符串 str
    • Unicode 字符串
    • 运算符
    • 空值 None
  • 第3章 流程控制

    • if 条件语句
    • if-else 条件语句
    • if-elif-else 多分支
    • 条件表达式(三元运算符)
    • while 循环
    • for 循环
    • range 与 xrange
    • 循环控制:break、continue、pass
    • 循环 else 子句
  • 第4章 数据结构

    • 列表基础
    • 列表方法
    • 列表推导式
    • 元组
    • 字典基础
    • 字典方法
    • 字典循环技巧
    • 集合
    • 序列解包
    • 序列比较
  • 第5章 函数

    • 定义函数
    • 参数传递机制
    • 默认参数
    • 关键字参数
    • 可变参数
    • Lambda 表达式
    • 文档字符串
    • 函数对象
  • 第6章 模块与包

    • import 导入
    • 模块搜索路径
    • name 与主程序
    • 编译文件 .pyc 与 .pyo
    • 包结构
    • dir() 函数
  • 第7章 文件与IO

    • 打开与关闭文件
    • 文件读写方法
    • with 上下文管理器
    • 格式化输出:% 操作符
    • 格式化输出:str.format()
    • JSON 序列化
  • 第8章 面向对象

    • 类定义与实例化
    • init 构造方法
    • 类变量与实例变量
    • 方法调用与 self
    • 继承基础
    • 多重继承
    • 新式类与旧式类
    • 私有变量与名称改写
    • 属性装饰器 property
    • 类方法与静态方法
    • 魔术方法
    • 空类与数据记录
  • 第9章 异常处理

    • 异常类型
    • try-except
    • try-except-else-finally
    • 抛出异常 raise
    • 自定义异常
    • with 语句与上下文管理器
  • 第10章 迭代器与生成器

    • 迭代器协议
    • 生成器函数
    • 生成器表达式
    • itertools模块
  • 第11章 标准库精要

    • os模块
    • sys模块
    • datetime模块
    • re模块
    • json模块
    • collections模块
    • math与random模块
    • urllib2与网络请求
    • subprocess与命令执行
    • threading与并发
    • unittest与测试
    • 虚拟环境与包管理
  • 第12章 工程实践

    • 调试技巧
    • 性能分析
    • 文档与注释
    • 下一步学习

JSON 序列化

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,人类易读、机器易解析。Python 的 json 模块提供了 JSON 编码(Python 对象 → JSON 字符串)和解码(JSON 字符串 → Python 对象)的功能。

基本用法

编码:dumps()

import json

data = {
    "name": "Alice",
    "age": 25,
    "is_student": False,
    "courses": ["Math", "Physics"],
    "address": None,
}

json_str = json.dumps(data)
print json_str
# {"courses": ["Math", "Physics"], "is_student": false, "name": "Alice", "age": 25, "address": null}

dumps() 把 Python 对象转换为 JSON 字符串。注意 JSON 的格式特点:

  • 键必须是双引号字符串
  • False 变成 false
  • None 变成 null
  • 字典键的顺序可能不同(Python 2 中字典无序)

解码:loads()

json_str = '{"name": "Bob", "age": 30}'
data = json.loads(json_str)
print data              # {u'age': 30, u'name': u'Bob'}
print type(data)        # <type 'dict'>

loads() 把 JSON 字符串转换为 Python 对象。Python 2 中,JSON 字符串解码为 unicode,数字解码为 int 或 float。

格式化输出

data = {"name": "Alice", "age": 25}

# 美化输出(缩进)
print json.dumps(data, indent=2)
# {
#   "age": 25,
#   "name": "Alice"
# }

# 自定义分隔符
print json.dumps(data, indent=2, separators=(",", ": "))
# {
#   "age": 25,
#   "name": "Alice"
# }

# 排序键
print json.dumps(data, indent=2, sort_keys=True)
# {
#   "age": 25,
#   "name": "Alice"
# }

处理中文

默认情况下,非 ASCII 字符被转义为 \uXXXX:

data = {"name": "张三"}
print json.dumps(data)
# {"name": "\u5f20\u4e09"}

# 保留中文
print json.dumps(data, ensure_ascii=False)
# {"name": "张三"}

ensure_ascii=False 让 dumps() 直接输出 Unicode 字符,而不是转义序列。写入文件时需要指定编码:

import codecs
with codecs.open("data.json", "w", "utf-8") as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

文件读写

# 写入文件
with open("data.json", "w") as f:
    json.dump(data, f, indent=2)

# 读取文件
with open("data.json", "r") as f:
    data = json.load(f)

dump() 和 load() 直接操作文件对象,dumps() 和 loads() 操作字符串。

类型映射

PythonJSON
dictobject
list, tuplearray
str, unicodestring
int, long, floatnumber
Truetrue
Falsefalse
Nonenull

注意:

  • JSON 不支持元组,tuple 被编码为数组,解码后变成 list
  • JSON 不支持 set
  • JSON 的键必须是字符串,Python dict 的整数键会被转为字符串
data = {1: "one", 2: "two"}
json_str = json.dumps(data)
print json_str          # {"1": "one", "2": "two"},键变成字符串

自定义编码

对于 JSON 不支持的对象(如 datetime、自定义类),需要自定义编码器:

import json
from datetime import datetime

class Person(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

def custom_encoder(obj):
    if isinstance(obj, datetime):
        return obj.isoformat()
    if isinstance(obj, Person):
        return {"name": obj.name, "age": obj.age}
    raise TypeError("Object of type %s is not JSON serializable" % type(obj))

now = datetime.now()
p = Person("Alice", 25)

print json.dumps({"time": now, "person": p}, default=custom_encoder)
# {"time": "2024-01-15T10:30:00", "person": {"age": 25, "name": "Alice"}}

实际应用

配置文件:

# config.json
{
    "host": "localhost",
    "port": 8080,
    "debug": false,
    "allowed_hosts": ["example.com", "api.example.com"]
}

# 读取配置
with open("config.json", "r") as f:
    config = json.load(f)
print config["host"]        # localhost

API 数据交换:

import urllib2

response = urllib2.urlopen("https://api.example.com/data")
data = json.load(response)
print data["users"][0]["name"]

与 pickle 的对比

特性JSONpickle
格式文本,人类可读二进制
跨语言是否(Python 专用)
安全性安全不安全(不要加载不信任的数据)
支持类型基本类型几乎所有 Python 对象
速度较慢较快

原则:数据交换用 JSON,Python 内部对象持久化用 pickle(但要确保数据来源可信)。

上一页
格式化输出:str.format()