
Json是一种轻量级的数据交换格式,易于人阅读和编写,现在大多服务的接口数据都使用Json进行传递。测试人员与Json免不了打交道。
Python官方提供了Json库供用户处理Json数据,包括4种方法:
dumps()
loads()
dump()
load()
这4种方法基本可以满足测试人员的需求。如果有性能更好、功能更多的需求,可以使用第三方库,如orjson、rapidjson、Pydantic。
本篇详细介绍如何使用 json.loads() 方法。
方法的作用
json.loads() 能够将 JSON 格式的字符串编码成 Python 对象。它接受一个 JSON 格式的字符串作为参数,然后将其转换成 Python 对象并返回,方便Python操作。
json 类型转换到 python 的类型对照表:
JSON | Python |
---|---|
object | dict |
array | list |
string | unicode |
number (int) | int, long |
number (real) | float |
true | True |
false | False |
null | None |
基本用法:
json.loads(s, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None)
各个参数中,s 是必选的,其他参数可选。
参数 s
指的是 JSON 格式的字符串。
import json
# 定义一个json格式的字符串
json_data = '{"Name": "JZY", "age": 18, "address": ["HangZhou", "XiHuQu"]}'
# 转换成 python 对象
dict_data = json.loads(json_data)
print(json_data, type(json_data)) # 打印json_data信息及类型,类型将是str
print(dict_data, type(dict_data)) # 打印json_data信息及类型,类型将是dict
print(dict_data["address"], type(dict_data["address"])) # 打印json_data中address的键对值信息及类型,类型将是list
运行结果
{"Name": "JZY", "age": 18, "address": ["HangZhou", "XiHuQu"]} <class 'str'>
{'Name': 'JZY', 'age': 18, 'address': ['HangZhou', 'XiHuQu']} <class 'dict'>
['HangZhou', 'XiHuQu'] <class 'list'>
参数 cls
默认为 None,用于指定一个自定义的 JSON 解码器类。这个类必须继承自 json.JSONDecoder,并且可以重写一些方法来实现自定义的解码逻辑。
import json
from datetime import datetime
# 定义一个自定义的 JSON 解码器类
class CustomDecoder(json.JSONDecoder):
def decode(self, s):
# 这里可以自定义解码逻辑
# 例如,将特定的字符串解析为 datetime 对象
# 定位date,解析为datetime 对象
decoded = super().decode(s)
if 'date' in decoded:
decoded['date'] = datetime.fromisoformat(decoded['date'].replace("'", ""))
return decoded
# JSON 字符串,其中包含一个日期字符串
json_string = '{"name": "JZY", "date": "2024-08-27T12:00:00"}'
# 不使用自定义的解码器类解析 JSON 字符串
data = json.loads(json_string)
# date的键对值类型为str
print(data, type(data["date"]))
# 使用自定义的解码器类解析 JSON 字符串
data = json.loads(json_string, cls=CustomDecoder)
# date的键对值类型为datetime.datetime
print(data, type(data["date"]))
运行结果
{'name': 'JZY', 'date': '2024-08-27T12:00:00'} <class 'str'>
{'name': 'JZY', 'date': datetime.datetime(2024, 8, 27, 12, 0)} <class 'datetime.datetime'>
参数 object_hook
默认为 None,接受一个函数,这个函数的参数是一个字典,返回值也是一个字典或任何其他Python对象。这个函数将对反序列化得到的每个字典对象进行处理。
import json
# 假设我们有一个JSON字符串
json_string_name = '{"name": "JZY", "age": 18, "is_student": false}'
# 定义一个自定义的类并新增参数
class Person:
def __init__(self, name, age, is_student):
self.name = name
self.age = age
self.is_student = is_student
# 定义一个object_hook函数
def object_hook(d):
if 'name' in d:
return Person(**d) # 使用字典解包来创建Person对象
return d
# 不使用object_hook参数解析JSON字符串
data = json.loads(json_string_name)
print(data, type(data))
# 使用object_hook参数解析JSON字符串
data = json.loads(json_string_name, object_hook=object_hook)
# 检查解码后的对象类型
print(data, type(data))
print(data.name) # 可以调用Person.name
运行结果
{'name': 'JZY', 'age': 18, 'is_student': False} <class 'dict'>
<__main__.Person object at 0x000001A6320E4C20> <class '__main__.Person'>
JZY
参数 parse_float
默认为 None,接受一个函数,这个函数应该接受一个字符串参数,并返回一个相应的浮点数值。这个函数将被用来解析 JSON 字符串中的数字,特别是那些应该被视为浮点数的数字。
import json
# 假设我们有一个包含特殊浮点数格式的JSON字符串
json_string = '{"value": 3.14159, "value1": 14.56987}'
# 定义一个自定义的parse_float函数
def parse_float(s):
return float(s) * 100 # 例如,将解析得到的浮点数乘以100
# 使用parse_float参数解析JSON字符串
data = json.loads(json_string, parse_float=parse_float)
print(data)
运行结果
{'value': 314.159, 'value1': 1456.987}
参数 parse_int
默认为 None,接受一个函数,这个函数应该接受一个字符串参数,并返回一个相应的整数或整数类型的对象。这个函数将被用来解析 JSON 字符串中的整数。
import json
# 假设我们有一个包含自定义格式整数的JSON字符串
json_string = '{"age": 25, "age1": 30}'
# 定义一个自定义的 parse_int 函数
def parse_int(s):
# 例如,我们想要将所有年龄增加10岁
return int(s) + 10
# 使用 parse_int 参数解析JSON字符串
data = json.loads(json_string, parse_int=parse_int)
print(data)
运行结果
{'age': 35, 'age1': 40}
参数 parse_constant
默认为 None,接受一个函数,这个函数应该接受一个不被JSON标准直接支持的非常量值(如 NaN, Infinity, -Infinity)字符串参数,并返回一个你希望的Python对象。
import json
# 假设我们有一个包含不被JSON标准直接支持的非常量值的字符串
json_string = '{"value1": NaN, "value2": Infinity, "value3": -Infinity}'
def parse_constant(value):
if value == 'NaN':
return None # 将 NaN 解析为 None
elif value == 'Infinity':
return float('inf') # 将 Infinity 解析为 Python 的正无穷大
elif value == '-Infinity':
return str('JZY') # 将 -Infinity 解析为 'JZY'
# 使用parse_constant参数解析JSON字符串
data = json.loads(json_string, parse_constant=parse_constant)
print(data) # 输出{'value1': None, 'value2': inf, 'value3': 'JZY'}
运行结果
{'value1': None, 'value2': inf, 'value3': 'JZY'}
参数 object_pairs_hook
默认为None,接受一个函数。这个函数将被用来处理解码后的项(键值对)。当JSON对象被解码成Python字典时,每一项(键值对)会作为参数传递给这个函数,然后这个函数的返回值将作为该项的最终值。`
import json
# 假设我们有一个JSON字符串
json_string = '{"name": "JZY", "age": 18, "is_student": false}'
# 定义一个object_pairs_hook函数
def object_pairs_hook(pairs):
# 这里可以自定义处理逻辑,例如将所有键转换为大写,upper()将小写字母转为大写
# {key.upper(): value for key, value in pairs} 是一个字典推导式,它的意思是key转为大写,value不变
return {key.upper(): value for key, value in pairs}
# 使用object_pairs_hook参数解析JSON字符串
data = json.loads(json_string, object_pairs_hook=object_pairs_hook)
print(data) # 输出: {'NAME': 'JZY', 'AGE': 18, 'IS_STUDENT': False}
运行结果
{'NAME': 'JZY', 'AGE': 18, 'IS_STUDENT': False}
请求中使用 loads() 示例
import requests
import json
# 目标URL
url = 'http://example.com/api/data'
# 发送请求
response = requests.get(url)
# 检查请求是否成功
if response.status_code == 200:
# 请求成功,处理返回的数据
data = json.loads(response.json()) # 假设返回的数据是JSON格式
print(data)
else:
# 请求失败,打印错误信息
print('Failed to retrieve data:', response.status_code)
json.load() 方法
json.dump()能从文件中读取 JSON 格式的数据,并将其解析为 Python 对象。 它接受一个参数,即包含 JSON 数据的文件对象。这个文件对象应该已经处于读取模式(通常是 ‘r’)。
基本用法:
json.loads(s, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None)
各个参数中,s 必选的,其他参数可选。json.load() 和 json.loads() 的唯一区别是 json.load() 是从文件中读取 JSON 格式的数据,操作对象是json文件。 对于其他参数,两者的用法是一样的。
import json
# 打开一个包含JSON数据的文件
with open('data.json', 'r', encoding='utf-8') as f:
# 使用json.load()从文件中读取并解析JSON数据
data = json.load(f)
print(data)
THEEND

© 转载需要保留原始链接,未经明确许可,禁止商业使用。CC BY-NC-ND 4.0
...