Json是是一种轻量级的数据交换格式,易于人阅读和编写,现在大多服务的接口数据都使用Json进行传递。测试人员与Json免不了打交道。

Python官方提供了Json库供用户处理Json数据,包括4种方法:

  • dumps()
  • loads()
  • dump()
  • load()

使用前要导入json模块:

import json

这4种方法基本可以满足测试人员的需求。如果有性能更好、功能更多的需求,可以使用第三方库,如orjson、rapidjson、Pydantic。

本篇详细介绍如何使用json.loads()方法。

关于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()方法的基本用法:

json.loads(s, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None)

json.loads()的各个参数中,s是必选的,其他参数可选。

s 参数

s是JSON格式的字符串。

import json

# 定义一个json格式的字符串
json_data = '{"Name": "JZY", "age": 18, "address": ["HangZhou", "XiHuQu"]}'

# 使用`json.loads()`转换成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'>

在这个例子中,我们创建了一个 CustomDecoder 类,它重写了 decode 方法来自定义解码逻辑。当解码后的字典中包含键 date 时,我们将其值从 ISO 格式的字符串转换为 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(type(data))


# 使用object_hook参数解析JSON字符串
data = json.loads(json_string_name, object_hook=object_hook)

# 检查解码后的对象类型
print(type(data))
print(data.name)  # 可以调用Person.name

运行结果

<class 'dict'>
<class '__main__.Person'>
JZY

在这个例子中,object_hook 函数检查传入的字典是否包含特定的键(在这个例子中是 “name”), 如果包含,就使用这些键值对来创建一个 Person 类的实例。当 json.loads() 被调用时并传入object_hook函数参数,它使用 object_hook 函数来处理解析得到的字典。

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}

运行结果

{'value': 314.159, 'value1': 1456.987}

在这个例子中,我们定义了一个 parse_float 函数,它将传入的字符串表示的浮点数乘以100。当 json.loads() 被调用时,它会使用这个函数来解析 JSON 字符串中的数字。

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}

运行结果

{'age': 35, 'age1': 40}

在这个例子中,我们定义了一个 parse_int 函数,它将传入的字符串表示的整数转换为基本整数类型,并增加了10。当 json.loads() 被调用时,它会使用这个函数来解析 JSON 字符串中的整数字段。

parse_constant 参数

默认为None。当json.loads()函数遇到不被JSON标准直接支持的非常量值(如 NaN, Infinity, -Infinity)时,通常会引发解析错误。但是,通过指定parse_constant参数,你可以定义一个自定义函数,该函数将处理这些值并返回你希望的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 解析为 Python 的负无穷大


# 使用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'}

在这个例子中,handle_constant函数被用来处理NaN, Infinity, 和 -Infinity,并将它们分别解析为None, float(‘inf’), 和str(‘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):
    # 这里可以自定义处理逻辑,例如将所有键转换为大写
    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}

在这个例子中,object_pairs_hook 函数被用来处理解码后的键值对列表。 在这个简单的例子中,我们只是将所有键转换为大写,但你可以在这里实现更复杂的逻辑,比如过滤某些键值对,或者将键值对列表转换为一个自定义对象。

请求中使用json.loads()

首先安装requests库。

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.dumps()能从文件中读取 JSON 格式的数据,并将其解析为 Python 对象。 它接受一个参数,即包含 JSON 数据的文件对象。这个文件对象应该已经处于读取模式(通常是 ‘r’)。

json.dump()方法的基本用法:

json.loads(s, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None)

json.load()的各个参数中,s必选的,其他参数可选。json.load()json.loads()的唯一区别是json.dump()是从文件中读取 JSON 格式的数据,操作对象是json文件。 对于其他参数,json.load()json.loads()的用法是一样的,不再赘述。

首先py当前目录下存在data.json文件,如图

import json

# 打开一个包含JSON数据的文件
with open('data.json', 'r', encoding='utf-8') as f:
    # 使用json.load()从文件中读取并解析JSON数据
    data = json.load(f)

print(data)

运行结果

{'lsh': 'random', 'hpzl': '01', 'hphm': '', 'clsbdh': 'LFNFVUMX0LAD25610', 'syr': '-', 'sxrq': '', 'zzrq': '', 'cllx': 'H11', 'syxz': 'F', 'zbzl': '11550', 'fdjh': '53429548', 'clpp1': '解放牌', 'clxh': 'CA1310P1K2L7T4E5A80'}

可以使用这个方法读取json文件中的值进行参数化请求或者进行其他操作。


THEEND



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