Python中从对象优先取两个属性之一、无匹配则返回默认值的优雅写法
Python优先获取指定属性的Pythonic实现方案
问题原因
你最初写的代码报错,核心是Python同级except只能捕获前面try代码块内抛出的异常:第一个except块中调用getattr(fruit_basket, "oranges")抛出的AttributeError,不会被同级的第二个except捕获,因此会直接向外抛出。
推荐实现方案
方案1:链式调用getattr(最简洁,双属性场景首选)
getattr支持传入第三个参数作为属性不存在时的返回默认值,直接嵌套即可实现优先级逻辑:
# FruitBasket 场景 n_fruits = getattr(fruit_basket, "apples", getattr(fruit_basket, "oranges", 0)) # sklearn 聚类器取质心场景 centroids = getattr(cluster_model, "clusters_centers_", getattr(cluster_model, "means_", []))
这个写法完全符合Pythonic风格,代码量最少,不需要额外引入逻辑,完全满足优先级要求:优先取第一个属性,不存在就取第二个,都不存在返回预设默认值。
方案2:通用工具函数(适合多属性扩展场景)
如果后续需要支持更多属性的优先级判断,可以封装一个通用工具函数,可复用性更强:
def get_first_exist_attr(obj, attr_priority: list, default=None): for attr in attr_priority: if hasattr(obj, attr): return getattr(obj, attr) return default # 调用示例 n_fruits = get_first_exist_attr(fruit_basket, ["apples", "oranges"], 0) centroids = get_first_exist_attr(cluster_model, ["clusters_centers_", "means_"], [])
可选方案:嵌套try-except
如果必须用异常捕获的写法,可以把第二个getattr放在嵌套的try-except块中,不过可读性和简洁度远不如上面两种方案:
try: n_fruits = getattr(fruit_basket, "apples") except AttributeError: try: n_fruits = getattr(fruit_basket, "oranges") except AttributeError: n_fruits = 0
内容的提问来源于stack exchange,提问作者Enrico Gandini
相关产品推荐
相关产品推荐

