Python中try块正常但except块无法捕获字典KeyError问题排查
问题原因
你写的catch_empty_key函数之所以没捕获到KeyError,是因为异常发生在函数调用之前:
当执行catch_empty_key(invoice['not_a_key'])时,Python会先计算传入函数的参数invoice['not_a_key']——这时候如果invoice里没有'not_a_key'这个键,直接就抛出了KeyError,根本没机会进入catch_empty_key的try块,自然触发不了函数里的except逻辑。
而当键存在时,invoice['not_a_key']能正常拿到值,参数传递成功,函数进入try块返回'aaaa',所以看起来正常。
解决办法
有三种常见的修复方式,根据需求选择:
方式一:修改自定义函数,传入字典和键
让函数内部处理字典键的访问,这样异常会被函数里的try-except捕获:
def catch_empty_key(invoice_dict, key): try: # 在这里访问字典键,异常会被内部的try块捕获 invoice_dict[key] return 'aaaa' except KeyError: return 'bbbb' # 列表推导式调用修改后的函数 data_2 = [catch_empty_key(invoice, 'not_a_key') for invoice in data1['invoices']]
注:捕获具体的KeyError而非裸except,能避免意外捕获其他无关异常,更规范。
方式二:在列表推导式内直接处理异常
不需要修改原函数,直接在遍历过程中处理每个元素的KeyError:
data_2 = [] for invoice in data1['invoices']: try: val = invoice['not_a_key'] data_2.append(catch_empty_key(val)) except KeyError: data_2.append('bbbb')
或者用更紧凑的条件判断写法:
data_2 = [ catch_empty_key(invoice['not_a_key']) if 'not_a_key' in invoice else 'bbbb' for invoice in data1['invoices'] ]
方式三:用字典get方法(最简洁)
如果只是判断键是否存在,直接用字典自带的get方法,不需要自定义函数:
# 利用get方法的默认值特性,或直接判断键是否存在 data_2 = ['aaaa' if 'not_a_key' in invoice else 'bbbb' for invoice in data1['invoices']]
内容的提问来源于stack exchange,提问作者Vishal Rathaur
相关产品推荐
相关产品推荐

