如何像Kotlin一样简单优雅访问深层嵌套且可能为空的JSON值?
问题描述
我需要获取JSON中深层嵌套的某一属性,问题在于访问路径上的部分节点可能为None,目前我采用多层嵌套if判断的方式实现,代码如下:
def name(x): x = x["relay_rendering_strategy"] if x: x = x["view_model"] if x: x = x["profile"] if x: x = x["event_place"] if x: x = x["contextual_name"] if x: return x.lower() return '' data = [x for x in get_events() if name(x) == 'ved siden af']
Kotlin中有非常简洁的语法可以实现相同效果,代码如下:
val name = first?.second?.third?.andSoFourth ?: ''
请问Python中是否有类似简洁易用的实现方式?
Python实现方案
这里给出三种常用的实现方式,均可以替代多层嵌套if判断:
1. 标准库functools.reduce实现(无额外依赖)
封装通用的嵌套安全取值函数,适合所有Python版本使用:
from functools import reduce def safe_nested_get(obj, key_path, default=''): try: res = reduce(lambda curr, key: curr[key] if curr else default, key_path, obj) return res.lower() if res else default except (KeyError, TypeError): return default # 调用示例 def name(x): return safe_nested_get(x, ["relay_rendering_strategy", "view_model", "profile", "event_place", "contextual_name"]) data = [x for x in get_events() if name(x) == 'ved siden af']
2. 海象运算符简化写法(Python 3.10+ 支持)
不需要额外封装函数,直接简化原有嵌套逻辑:
def name(x): if (x := x.get("relay_rendering_strategy")) \ and (x := x.get("view_model")) \ and (x := x.get("profile")) \ and (x := x.get("event_place")) \ and (x := x.get("contextual_name")): return x.lower() return ''
3. 第三方库glom实现(写法最接近Kotlin)
如果允许引入第三方依赖,glom库的语法和Kotlin空安全调用非常接近,代码更简洁:
from glom import glom def name(x): return glom(x, "relay_rendering_strategy.view_model.profile.event_place.contextual_name", default='').lower()
内容的提问来源于stack exchange,提问作者mama
相关产品推荐
相关产品推荐

