json操作是最为基本的、最为常用的,Python自带的json模块就可以满足大部分应用场景,而且使用起来极为简单,没几行代码。。
案例分为几个步骤,一层层剖析json包的参数用法,大概有以下几个步骤:基本用法、自定义序列化、嵌套序列化、数字格式化、四舍五入、cls参数的意义
每一行代码都是精华,好好的欣赏一下吧,全部代码如下:
import decimal
import json
print('\033[1;37;41m step 1:基本用法 \033[0m ')
# 先在本文件目录下,新建 1.json、2.json 两个文件
# 其中,1.json 的内容如下
'''
{
"a": "yunfeng",
"b": "xiaohong",
"c": [
{
"c1": "123"
}
]
}
'''
# 读取 json 文件
with open('1.json', 'r') as f:
json_str = f.readlines()
json_str = ''.join(json_str)
print('json 字符串:', json_str)
# 转换为字典
a = json.loads(json_str) # loads 读取 json 字符串
print('字典:', a['a'])
# 一步到位
with open('1.json', 'r') as f:
a = json.load(f) # load 读取 json 文件
print('字典:', a['a'])
# 再转换为字符串
json_str = json.dumps(a)
print('json 字符串:', json_str)
# 写入文件
with open('2.json', 'w') as f:
# 格式化、避免中文乱码
json.dump(a, f, indent=4, ensure_ascii=False)
print('\033[1;37;41m step 2:自定义序列化 \033[0m ')
from collections import OrderedDict
# 转为有序的键值,可解决嵌套json
a = json.loads(json_str, object_pairs_hook=OrderedDict)
print(a)
print(a.pop('a'))
# 下面演示键值提取,不能用于存在嵌套的json
def test_dict(d: dict):
print(type(d), d)
def test_list_dict(lt: list):
print(type(lt), lt)
# 注意:'c': [None]
json.loads(json_str, object_hook=lambda x: test_dict(x)) # 每一层当作字典装载
json.loads(json_str, object_pairs_hook=lambda x: test_list_dict(x)) # 每一层当作列表装载
print('\033[1;37;41m step 3:嵌套序列化 \033[0m ')
# 解决嵌套json结构反序列化:https://nvie.com/posts/modifying-deeply-nested-structures/
def traverse(obj):
if isinstance(obj, dict):
value = {k: traverse(v)
for k, v in obj.items()}
elif isinstance(obj, list):
value = [traverse(elem)
for elem in obj]
else:
value = obj
return value
a = json.loads(json_str, object_hook=lambda x: traverse(x))
print(a)
print('\033[1;37;41m step 4:数字格式化、四舍五入 \033[0m ')
def my_round(x):
# print(x) # 只有float类型的值,才会调用到此函数
return decimal.Decimal(str(round(float(x), 2))) # 保留两位小数
def error_number(x):
print('检查到正负无穷大、NaN等非法数字:', x)
return 0 # 处理为 0
a = json.loads(json_str, parse_float=lambda x: my_round(x), parse_constant=lambda x: error_number(x)) # 只有float类型的值,才会调用到此函数
print(a)
print('\033[1;37;41m step 5:cls参数的意义 \033[0m ')
# python中cls代表的是类的本身,相对应的self则是类的一个实例对象。
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
print('self是指实例对象:', self)
# 定义一个build方法,返回一个person实例对象,这个方法等价于Person()。
@classmethod
def build(cls):
# cls()等于Person()
p = cls("Tom", 18)
print('cls是指类本身', cls)
return p
person = Person.build()
print('实例对象:', person)
print('值:' + person.name, person.age)
from json import JSONDecoder
class MyJSONDecoder(JSONDecoder):
pass
a = json.loads(json_str, cls=MyJSONDecoder) # 自定义解码器
print(a)
运行结果