考虑以下 Python 代码:
def say(words):
for word in words:
if word == "Ni":
raise ValueError("We are no longer the knights who say Ni!")
print(word)
def blackbox(function, sentence):
words = sentence.split()
try:
function(words)
except Exception as e:
raise RuntimeError("Generic Error")
blackbox(say, "Foo Ni Bar")
它打印以下回溯:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Input In [35], in blackbox(function, sentence)
9 try:
---> 10 function(words)
11 except Exception as e:
Input In [35], in say(words)
3 if word == "Ni":
----> 4 raise ValueError("We are no longer the knights who say Ni!")
5 print(word)
ValueError: We are no longer the knights who say Ni!
During handling of the above exception, another exception occurred:
RuntimeError Traceback (most recent call last)
Input In [35], in <cell line: 14>()
11 except Exception as e:
12 raise RuntimeError("Generic Error")
---> 14 blackbox(say, "Foo Ni Bar")
Input In [35], in blackbox(function, sentence)
10 function(words)
11 except Exception as e:
---> 12 raise RuntimeError("Generic Error")
RuntimeError: Generic Error
假设我只对第一个错误感兴趣。我可以简单地通过将
raise RuntimeError("Generic Error")
中的 raise e
替换为 blackbox()
来重新提高它:故事结束。
除了(!)我无法修改属于外部库的
blackbox()
的代码。
如何在不碰它的情况下获得相同的结果?我的猜测是,我可以将对
blackbox()
的调用包装在 try... except...
中,检索异常链,然后选择我感兴趣的异常。但我没能在任何地方找到如何做这样的事情。
编辑:更改了第二个函数的名称和签名以使约束更清晰。
回答我自己的问题。捕获最终的异常及其上下文就足够了,即将最后一行替换为:
raise
追溯:
try:
blackbox(say, "Foo Ni Bar")
except Exception as e:
raise e.__context__