JSON 数据格式详解_json格式
1. JSON 概念
JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式:
- 人类可读的文本格式
- 完全独立于编程语言
- 用于存储和传输结构化数据
- 广泛应用于API通信、配置文件和数据存储
2. JSON 核心原理
- 键值对结构:类似字典的概念
- 树状层级:支持嵌套数据结构
- 数据类型支持:字符串、数字、布尔值、数组、对象、null
- 无状态:不包含函数或可执行代码
- 文本格式:使用纯文本表示,默认UTF-8编码
3. JSON 语法规范
基本结构
{ \"key1\": \"value\", \"key2\": 42, \"key3\": true, \"key4\": null, \"key5\": [\"数组\", \"元素\"], \"key6\": { \"nested\": \"嵌套对象\" }}
语法规则
- 键名:必须用双引号包裹
- 字符串值:必须用双引号包裹
- 数据类型:
- 字符串:
\"text\"
- 数字:
123
或3.14
- 布尔值:
true
或false
- null:
null
- 数组:
[值1, 值2]
- 对象:
{\"key\": value}
- 字符串:
- 分隔符:
- 键值对用冒号
:
分隔 - 元素用逗号
,
分隔
- 键值对用冒号
- 不支持特性:
- 注释
- 尾随逗号
- 十六进制数字
4. JSON API 功能(Python)
核心函数
json.dump()
obj
, fp
, indent
, ensure_ascii
json.dumps()
obj
, indent
, separators
, default
json.load()
fp
, object_hook
, parse_float
json.loads()
s
, object_hook
, parse_int
关键参数说明
-
序列化参数:
indent
:缩进空格数(美化输出)ensure_ascii=False
:允许非ASCII字符(如中文)default
:自定义对象序列化函数separators=(\',\', \':\')
:紧凑格式
-
反序列化参数:
object_hook
:自定义字典转换函数parse_float
:自定义浮点数解析parse_int
:自定义整数解析
5. JSON 处理流程
#mermaid-svg-48tB5TxW9eCTdOPg {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-48tB5TxW9eCTdOPg .error-icon{fill:#552222;}#mermaid-svg-48tB5TxW9eCTdOPg .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-48tB5TxW9eCTdOPg .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-48tB5TxW9eCTdOPg .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-48tB5TxW9eCTdOPg .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-48tB5TxW9eCTdOPg .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-48tB5TxW9eCTdOPg .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-48tB5TxW9eCTdOPg .marker{fill:#333333;stroke:#333333;}#mermaid-svg-48tB5TxW9eCTdOPg .marker.cross{stroke:#333333;}#mermaid-svg-48tB5TxW9eCTdOPg svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-48tB5TxW9eCTdOPg .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-48tB5TxW9eCTdOPg .cluster-label text{fill:#333;}#mermaid-svg-48tB5TxW9eCTdOPg .cluster-label span{color:#333;}#mermaid-svg-48tB5TxW9eCTdOPg .label text,#mermaid-svg-48tB5TxW9eCTdOPg span{fill:#333;color:#333;}#mermaid-svg-48tB5TxW9eCTdOPg .node rect,#mermaid-svg-48tB5TxW9eCTdOPg .node circle,#mermaid-svg-48tB5TxW9eCTdOPg .node ellipse,#mermaid-svg-48tB5TxW9eCTdOPg .node polygon,#mermaid-svg-48tB5TxW9eCTdOPg .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-48tB5TxW9eCTdOPg .node .label{text-align:center;}#mermaid-svg-48tB5TxW9eCTdOPg .node.clickable{cursor:pointer;}#mermaid-svg-48tB5TxW9eCTdOPg .arrowheadPath{fill:#333333;}#mermaid-svg-48tB5TxW9eCTdOPg .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-48tB5TxW9eCTdOPg .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-48tB5TxW9eCTdOPg .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-48tB5TxW9eCTdOPg .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-48tB5TxW9eCTdOPg .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-48tB5TxW9eCTdOPg .cluster text{fill:#333;}#mermaid-svg-48tB5TxW9eCTdOPg .cluster span{color:#333;}#mermaid-svg-48tB5TxW9eCTdOPg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-48tB5TxW9eCTdOPg :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;}json.dumpsjson.loadsjson.dumpjson.loaddefault函数object_hookPython对象JSON字符串Python对象JSON文件自定义对象可序列化字典
6. 应用示例
示例1:基本序列化与反序列化
输入(Python对象):
data = { \"server\": \"web01\", \"status\": \"online\", \"ports\": [80, 443], \"active\": True}
序列化:
import json# 转换为JSON字符串json_str = json.dumps(data, indent=2)print(json_str)
输出(JSON字符串):
{ \"server\": \"web01\", \"status\": \"online\", \"ports\": [ 80, 443 ], \"active\": true}
反序列化:
# 从JSON字符串转换回Python对象restored_data = json.loads(json_str)print(restored_data[\"ports\"][0]) # 输出: 80
示例2:文件读写
写入JSON文件:
config = { \"database\": { \"host\": \"db.example.com\", \"port\": 3306, \"user\": \"admin\" }, \"timeout\": 30}with open(\"config.json\", \"w\") as f: json.dump(config, f, indent=4)
生成的config.json:
{ \"database\": { \"host\": \"db.example.com\", \"port\": 3306, \"user\": \"admin\" }, \"timeout\": 30}
读取JSON文件:
with open(\"config.json\", \"r\") as f: loaded_config = json.load(f) print(loaded_config[\"database\"][\"host\"]) # 输出: db.example.com
示例3:处理自定义对象
自定义设备类:
class NetworkDevice: def __init__(self, name, ip): self.name = name self.ip = ip
序列化自定义对象:
def device_encoder(obj): if isinstance(obj, NetworkDevice): return {\"device_name\": obj.name, \"ip_address\": obj.ip} raise TypeError(\"不可序列化的对象\")router = NetworkDevice(\"core-router\", \"10.0.0.1\")json_str = json.dumps(router, default=device_encoder)print(json_str)# 输出: {\"device_name\": \"core-router\", \"ip_address\": \"10.0.0.1\"}
反序列化自定义对象:
def device_decoder(dct): if \"device_name\" in dct and \"ip_address\" in dct: return NetworkDevice(dct[\"device_name\"], dct[\"ip_address\"]) return dctdevice = json.loads(json_str, object_hook=device_decoder)print(f\"{device.name}: {device.ip}\") # 输出: core-router: 10.0.0.1
示例4:处理特殊数据类型
输入(包含日期):
from datetime import datetimelog_entry = { \"event\": \"login\", \"user\": \"alice\", \"timestamp\": datetime.now()}
自定义序列化:
def custom_serializer(obj): if isinstance(obj, datetime): return obj.isoformat() return str(obj) # 其他类型转为字符串json_str = json.dumps(log_entry, default=custom_serializer)print(json_str)
输出:
{ \"event\": \"login\", \"user\": \"alice\", \"timestamp\": \"2023-11-15T14:30:45.123456\"}
7. 常见错误处理
invalid_json = \"{\'key\': \'value\'}\" # 错误:JSON要求双引号try: data = json.loads(invalid_json)except json.JSONDecodeError as e: print(f\"JSON解析错误: {e.msg}\") print(f\"位置: 行 {e.lineno}, 列 {e.colno}\") # 实际输出: JSON解析错误: Expecting property name enclosed in double quotes
8. 最佳实践
-
美化与压缩:
- 开发环境:使用
indent=2
方便阅读 - 生产环境:使用
separators=(\',\', \':\')
减少体积
- 开发环境:使用
-
中文支持:
data = {\"name\": \"服务器\"}json_str = json.dumps(data, ensure_ascii=False) # 正确显示中文
-
数据类型转换:
- JSON数字 → Python int/float
- JSON数组 → Python list
- JSON对象 → Python dict
- JSON null → Python None
-
安全注意:
- 不要解析不可信来源的JSON
- 设置最大解析深度:
json.loads(data, max_depth=10)
JSON是现代应用中最常用的数据交换格式,掌握它的基本使用和Python处理技巧,是自动化运维和开发的基础能力。从配置文件到API通信,JSON无处不在!