如何获取嵌套属性值?属性缺失时返回默认值(含JIRA场景)
如何在属性可能不存在时链式获取嵌套属性?
我尝试构造列表推导式,生成包含issues中每个元素的fields.parent.id值的列表,当不存在parent属性时返回None。是否有一种简单的方式获取attribute1.attribute2.attribute3,且在中间属性不存在时返回默认值?
相关类型信息:
>>> type(issue) <class 'jira.resources.Issue'> >>> type(issue.fields) <class 'jira.resources.PropertyHolder'> >>> type(issue.fields.parent) <class 'jira.resources.Issue'>
示例场景:
>>> issues[0].fields.parent.id '12345' >>> issues[1].fields.parent.id AttributeError: 'PropertyHolder' object has no attribute 'parent'
期望得到列表:['12345', None]
尝试过的方法都有问题:
- 直接推导式会报错:
>>> [i.fields.parent.id for i in issues] AttributeError: 'PropertyHolder' object has no attribute 'parent' - 添加if过滤会遗漏None值:
>>> [i.fields.parent.id for i in issues if hasattr(i.fields, 'parent')] ['12345'] - 单层getattr只能返回parent对象而非id:
>>> [getattr(i.fields, 'parent', None) for i in issues] [<JIRA Issue: key='PRJ-1', id='12345'>, None] - 定义函数可以实现,但代码繁琐,且有大量类似需求:
>>> def parent_id(issue): ... if hasattr(issue.fields, 'parent'): ... return issue.fields.parent.id ... else: ... return None >>> [parent_id(i) for i in issues] ['12345', None]
是否有更简洁/优雅的实现方式?
解决方案
1. 嵌套使用getattr(最简洁直接)
通过多层嵌套getattr,为每一层可能不存在的属性设置默认值None,最终就能得到目标结果:
[getattr(getattr(i.fields, 'parent', None), 'id', None) for i in issues]
原理:如果i.fields没有parent属性,第一个getattr返回None;接着对None调用getattr取id,同样返回None,完美匹配需求。
2. 利用EAFP原则的try-except写法
Python推崇“请求原谅比许可容易”的风格,可结合try-except实现:
# 循环写法(直观易读) result = [] for issue in issues: try: result.append(issue.fields.parent.id) except AttributeError: result.append(None)
3. 通用嵌套属性获取函数(适合大量类似需求)
如果有很多链式属性获取的需求,可封装一个通用工具函数,用functools.reduce批量处理属性路径:
from functools import reduce def get_nested_attr(obj, attr_path, default=None): return reduce(lambda o, attr: getattr(o, attr, default), attr_path.split('.'), obj) # 使用方式: [get_nested_attr(i, 'fields.parent.id') for i in issues]
这个函数可以处理任意深度的嵌套属性,比如get_nested_attr(obj, 'a.b.c.d'),只要中间某层不存在就返回默认值None。
内容的提问来源于stack exchange,提问作者weegolo
相关产品推荐
相关产品推荐

