读取嵌套JSON遇NoneType错误,如何替代大量try/except?
解决嵌套JSON取值的NoneType下标访问问题
你遇到的错误是:类型错误:‘NoneType’对象不可下标访问,本质是嵌套路径中某一层返回了None(比如某个键不存在、列表为空或索引越界),后续的下标操作就会触发这个错误。逐个写try/except确实繁琐,下面是几种更简洁的原生解决方案:
方案1:封装通用取值函数
写一个可复用的函数,遍历嵌套路径,自动处理不存在的键、空列表、None等情况,返回默认值:
def get_nested_value(data, path, default=''): current = data for key in path: try: if isinstance(current, dict): # 字典用get方法,不存在则返回None current = current.get(key, None) elif isinstance(current, list) and isinstance(key, int): # 列表检查索引是否有效 current = current[key] if key < len(current) else None else: # 既不是字典也不是列表,无法继续取值 current = None except (KeyError, IndexError, TypeError): # 捕获键不存在、索引越界、类型错误等异常 current = None if current is None: # 任意一步出现None,直接返回默认值 return default return current if current is not None else default
改写你的代码
用这个函数替换原来的try/except块,代码会简洁很多:
import json # 上面的get_nested_value函数放在这里 # 修正JSON读取方式:json.loads接收字符串,json.load接收文件对象 with open('json_file.json', 'r', encoding='utf-8') as f: data = json.load(f) for nodesUni in data["data"]["queryUnits"]['nodes']: # 用路径列表指定嵌套层级 engine_type = get_nested_value(nodesUni, ['sql', 'busData', 0, 'engine', 'engType']) engine_name = get_nested_value(nodesUni, ['sql', 'carData', 0, 'engineData', 'producer', 'engName']) json_output_for_one_GU_owner = { "EngineType": engine_type, "EngineName": engine_name, } # 这里可以添加输出/存储逻辑 print(json_output_for_one_GU_owner)
方案2:用functools.reduce简化(可读性稍弱)
如果喜欢更简洁的写法,可以结合functools.reduce实现:
from functools import reduce def get_nested_value(data, path, default=''): def _access_item(obj, key): try: if isinstance(obj, dict): return obj.get(key, None) elif isinstance(obj, list) and isinstance(key, int): return obj[key] if key < len(obj) else None return None except (TypeError, IndexError): return None result = reduce(_access_item, path, data) return result if result is not None else default
用法和方案1完全一致,只是内部实现用了reduce来遍历路径。
内容的提问来源于stack exchange,提问作者Piranha
相关产品推荐
相关产品推荐

