当前位置: 首页 > news >正文

python中修改局部json的思路

背景

希望修改某个路径下的字段,但是不希望覆盖其他字段。

{"name": "张三","age": 18
}

类似于上下对比这样。

{"name": "张三","age": 21
}

方案

get - set

使用get获取整个对象,然后修改整个对象后使用set。

回调函数

def callback(obj):obj['age'] = 21return obj

隔应的地方有两点:

  1. python的匿名函数只能有一条表达式,因此即使是上面这种简单的语句也得写一个具名函数,非常啰嗦。
  2. 事实上在执行obj['age'] = 21的时候值的修改已经完成(对象的话),但是考虑到还有字符串等简单数值,因此还是有返回值,并且内部有赋值操作。因此如果是对象的话,会有一次无效的赋值。(类似于obj=obj)

总的来说,完全没有简洁性可言。

pydash

image
比较完美地解决了问题,但是我不希望这种小问题都引入一个库。

自设计路径

仅仅是思路,因此直接使用ai代码做示例。

import json
from pathlib import Path
from datetime import datetimedef update_json_field_by_path(file_path: str, indices_and_keys: list, new_value: any) -> bool:"""通过指定索引和键的路径,安全地修改 JSON 文件中的值。Args:file_path: JSON 文件的路径。indices_and_keys: 从根到目标字段的路径列表。例如: ["hika", "latest_login"] 或 [0, "hika", "latest_login"]new_value: 要写入的新值。Returns:bool: 如果成功找到并更新了字段,返回 True;否则返回 False。"""file = Path(file_path)# --- 1. 读取数据 ---try:if not file.exists():print(f"错误:文件不存在于路径 '{file_path}'")return Falsewith open(file, 'r', encoding='utf-8') as f:data = json.load(f)except Exception as e:print(f"读取或解析 JSON 文件时发生错误: {e}")return False# --- 2. 遍历路径找到目标字段 ---current_level = datapath_trace = []try:# 遍历路径列表,直到倒数第二个元素 (即目标字段的父级)for i, key_or_index in enumerate(indices_and_keys[:-1]):path_trace.append(str(key_or_index))# 检查当前级别是否包含下一个键/索引if isinstance(current_level, list):# 如果是列表,期望 key_or_index 是整数索引current_level = current_level[int(key_or_index)]elif isinstance(current_level, dict):# 如果是字典,期望 key_or_index 是字符串键current_level = current_level[str(key_or_index)]else:raise TypeError(f"路径错误:'{key_or_index}' 无法应用于 {type(current_level).__name__} 类型。路径终止于:{' -> '.join(path_trace)}")# 最终的键/字段名是路径列表的最后一个元素final_key = indices_and_keys[-1]# --- 3. 修改目标字段 ---if isinstance(current_level, dict) and str(final_key) in current_level:# 这一步是关键:只修改了内存中 data 变量的深层嵌套字段current_level[str(final_key)] = new_valueprint(f"字段路径 {' -> '.join(path_trace + [str(final_key)])} 已更新为: {new_value}")else:print(f"错误:无法在路径 {' -> '.join(path_trace)} 中找到字段 '{final_key}' 或目标不是字典。")return Falseexcept (IndexError, KeyError, TypeError, ValueError) as e:print(f"错误:无效的路径或结构不匹配。详细错误: {e}")return False# --- 4. 写入数据 (覆盖原文件) ---try:with open(file, 'w', encoding='utf-8') as f:# 使用 indent=4 保持文件格式美观json.dump(data, f, indent=4, ensure_ascii=False)return Trueexcept Exception as e:print(f"写入文件时发生错误: {e}")return False# ----------------------------------------------------
# 演示使用
# ----------------------------------------------------
USER_FILE = "users.json"
# 使用当前时间作为新值
current_time = datetime.now().isoformat(timespec='seconds')# --- 运行示例 ---
# 1. 初始化文件 (请确保文件结构与示例假设一致)
initial_data = [{"hika": {"latest_login": "", "email": "h.nagi@example.com"}, "id": 1},{"xxgal": {"latest_login": "", "email": "x.gal@example.com"}, "id": 2}
]
with open(USER_FILE, 'w', encoding='utf-8') as f:json.dump(initial_data, f, indent=4)print("--- 原始文件内容 ---")
print(open(USER_FILE, 'r', encoding='utf-8').read())
print("--------------------")# 目标:修改 data[0]['hika']['latest_login']
path_to_modify = [0, "hika", "latest_login"]
update_successful = update_json_field_by_path(USER_FILE, path_to_modify, current_time)if update_successful:print("\n--- 更新后的文件内容 (验证是否只修改了目标字段) ---")print(open(USER_FILE, 'r', encoding='utf-8').read())print("-------------------------------------------------------")

结论

折腾来折腾去,还不如直接获取然后修改。看上去不简洁的方法,反而变成了最简洁的方法。

http://www.hskmm.com/?act=detail&tid=30302

相关文章:

  • LSNet
  • Webpack 构建速度优化
  • [模拟赛] 过关(pass)
  • 2025.10.13
  • 第十三节:基于 Redis+MQ+DB实现高并发秒杀下的扣减
  • c++初体验
  • 元宇宙的搜索引擎:如何在虚拟世界中查找信息 - 详解
  • 四则运算错题本和错题重做的建立
  • 行列式的性质
  • 04_SQL语句一
  • 死锁的原因、表现以排查
  • 详细介绍:【C++】二叉搜索树
  • 朱世乐的 Johnson 算法笔记
  • day010
  • 20232323 2025-2026-1《网络与系统攻防技术》实验一实验报告
  • 树莓派4B安装WiringPi使用gpio命令
  • 单调队列优化 dp
  • 1分钟Get宠物神兽壁纸我家猫被问疯了!
  • Zabbix 6.0+ 运用官方模板监控 Redis 数据库的完整安装指南
  • 【图论】Floyd算法简析
  • MyEclipse 2017 激活教程
  • 插入 dp
  • 05_Mysql与图片的存储
  • 【Linux】权限 - 实践
  • 斯坦福ACE框架:让AI自己学会写prompt,性能提升17%成本降87%
  • 【左扬精讲】SRE 别慌!我用 服务器监控指标 讲 KNN 分类算法,从相似度计算到异常识别,都是咱运维人能懂的话(含代码)
  • 博客园地址 - yuyue
  • 【终章】:幸福的复利——打造你的每日幸福微习惯 - 指南
  • 实用指南:Go 语言中的**数组 (Array)*用法
  • 行业词汇