
我们在日常做自动化测试的时候,会经常和很多的文件打交道,比如 JSON、YAML、Excel 等。上周,我的测试同事LINA就遇到了一个问题:需要找到原 json 文件中的物流单号,并更新,保存后再读取使用
也就是说,整个流程涉及 JSON 文件的读取、定位、修改、保存再调用。去网上找教程,再编写代码的时候发现 “教程一看就会,实际上手一下就废” 😂
我们一起来看个热闹吧😏
用Python去操作JSON文件最常见的的方法
1、读取JSON文件
import json
# 直接读取
with open('data.json', 'r', encoding='utf-8') as f:
data = json.load(f)
print(data)
2、更新JSON文件内容
import json
# 读取文件
with open('data.json', 'r', encoding='utf-8') as f:
data = json.load(f)
# 修改数据,假设json中有数据
data['age'] = 26 # 修改数据
data['city'] = '北京' # 添加新字段
data.pop('old_field', None) # 删除字段
print("修改后的Json为:", data)
3、写入并保存JSON文件
import json
# 新json数据
data = {
"name": "李四",
"age": 28,
"hobbies": ["阅读", "游泳", "编程"]
}
# 保存到文件
with open('output.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
没有了,基础操作就这三个!网上的教程就是这么的简单明了 🤣
但到了实际的工作中就会发现:完全没有这么简单的 JSON文件!
全是这种嵌套、嵌套、再嵌套的树型结构(这还是小编精简过的,全部JSON有200多行呢😂)
在这样复杂的结构里,想要准确定位并修改某个字段(比如 tracking_number),那是一件令人头秃的事情
{
"system_info": {
"api_version": "v2.1",
"environment": "production",
"data_refresh_time": "2023-12-15T14:30:00Z"
},
"orders": {
"ORD-20231215-0001": {
"order_id": "ORD-20231215-0001",
"customer": {
"customer_id": "CUS-10001",
"name": "张三",
"phone": "13800138000"
},
"order_summary": {
"status": "processing",
"payment_status": "paid",
"total_amount": 2299.00,
"created_at": "2023-12-15T10:15:30Z"
},
"products": [
{
"sku": "SM-G9901",
"name": "三星Galaxy S23 5G手机",
"quantity": 1,
"unit_price": 1999.00
},
],
"shipping": {
"tracking_number": "SF10023456789",
"carrier": "顺丰速运",
"estimated_delivery": "2023-12-18"
}
},
"ORD-20231214-0034": {
"order_id": "ORD-20231214-0034",
"customer": {
"customer_id": "CUS-10045",
"name": "李四",
"phone": "13900139000"
},
"order_summary": {
"status": "shipped",
"payment_status": "paid",
"total_amount": 864.00,
"created_at": "2023-12-14T15:45:20Z"
},
"products": [
{
"sku": "APP-WATCH-01",
"name": "Apple Watch Series 9",
"quantity": 1,
"unit_price": 899.00
}
],
"shipping": {
"tracking_number": "YT1234567890",
"carrier": "圆通速递",
"estimated_delivery": "2023-12-20"
}
}
},
"statistics": {
"total_orders": 3,
"total_revenue": 4662.00,
"orders_by_status": {
"processing": 1,
"shipped": 1,
"delivered": 1
}
}
}
虽然JSON文件复杂,但好在树型结构是有逻辑可寻的,而JSON操作逻辑依然是:逐层定位 → 修改 → 保存
要更新的物流单号是在 orders → 具体订单 → shipping → tracking_number 这个路径下
{
"orders": {
"ORD-20231215-0001": {
"order_summary": {
"status": "processing"
},
"shipping": {
"tracking_number": "SF10023456789"
}
}
}
}
让我们从最简单的开始:读取JSON文件并获取到订单号
import json
def read_json_file(filename):
"""读取JSON文件"""
try:
with open(filename, 'r', encoding='utf-8') as f:
data = json.load(f)
for order_key in data['orders'].keys():
print(f"订单编号:{order_key}")
except FileNotFoundError:
print(f"文件 {filename} 不存在")
returnNone
if __name__ == '__main__':
# 读取订单号
read_json_file('data_text.json')
运行结果:
订单编号:ORD-20231215-0001
订单编号:ORD-20231214-0034
订单编号:ORD-20231213-0123
import json
def read_json_file(filename):
"""读取JSON文件"""
try:
with open(filename, 'r', encoding='utf-8') as f:
data = json.load(f)
# 获取订单键列表
order_keys = list(data['orders'].keys())
print(order_keys)
# 获取第二个订单号
order_key = order_keys[1]
# 获取第二个订单所有数据
target_order = data['orders'][order_key]
# 获取物流编号
tracking_number = target_order['shipping']['tracking_number']
print(tracking_number)
except FileNotFoundError:
print(f"文件 {filename} 不存在")
returnNone
if __name__ == '__main__':
# 读取物流号
read_json_file('data_text.json')
运行结果:
['ORD-20231215-0001', 'ORD-20231214-0034', 'ORD-20231213-0123']
订单编号为:YT9876543210
这里一定要注意:修改数据后,必须保存文件,否则所有操作仅存在于内存中
import json
def read_json_file(filename):
"""读取JSON文件"""
try:
with open(filename, 'r', encoding='utf-8') as f:
data = json.load(f)
# 获取订单键列表
order_keys = list(data['orders'].keys())
print(order_keys)
# 获取第二个订单号
order_key = order_keys[1]
# 获取第二个订单所有数据
target_order = data['orders'][order_key]
# 获取物流编号并修改
tracking_number = target_order['shipping']['tracking_number'] = 'sf102928377'
print(f"新物流编号为:{tracking_number}")
# 写回JSON文件
with open(filename, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=4, ensure_ascii=False)
print(f"文件 {filename} 更新完成!")
return data
except FileNotFoundError:
print(f"文件 {filename} 不存在")
returnNone
if __name__ == '__main__':
# 读取并修改物流号
read_json_file('data_text.json')
import json
def read_json_file(filename, num, new_code):
"""
:param filename: json文件名
:param num: 订单号
:param new_code: 新物流单号
:return:
"""
try:
with open(filename, 'r', encoding='utf-8') as f:
data = json.load(f)
# 获取订单号键列表
order_keys = list(data['orders'].keys())
# 获取第N个订单号
order_key = order_keys[num]
# 获取第N个订单的所有数据
target_order = data['orders'][order_key]
# 获取物流单号,并修改
tracking_number = target_order['shipping']['tracking_number'] = new_code
print(f"新物流单号为:{tracking_number}")
# 写回JSON文件
with open(filename, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=4, ensure_ascii=False)
print(f"文件 {filename} 更新完成!")
return data
except FileNotFoundError:
print(f"文件 {filename} 不存在")
returnNone
if __name__ == '__main__':
# 修改指定的物流单号
read_json_file('data_text.json', 1, 'SF1234567989')
其实这套代码还缺少对应的异常处理,增加代码健壮性。但就像那句网上的经典名言:能跑通的代码就不动,出bug了再补救吧😂
点赞噢~