如何在函数执行完成后抛出并捕获异常?解决代码执行与异常处理冲突
解决异常抛出后仍执行代码并传递结果的问题
看起来你的核心需求是:foo函数在触发CustomException后,既要完成后续代码生成resultIwant,又要让bar函数能捕获到这个异常,同时拿到最终的resultIwant。目前的困境是要么foo被异常中断拿不到结果,要么捕获异常后bar的except块无法触发。这里有几个可行的方案:
方案一:将结果附着在异常对象上传递
首先调整你的CustomException,让它可以携带结果数据:
class CustomException(Exception): def __init__(self, result=None, *args, **kwargs): super().__init__(*args, **kwargs) self.result = result # 存储生成好的结果
然后修改foo函数,先完成resultIwant的生成,再判断是否抛出异常——这样即使抛出异常,结果已经存在了:
def foo(): # good code # 先执行生成resultIwant的逻辑,无论是否触发异常都要生成结果 resultIwant = 生成结果的代码() if thingThatHappensSometimes: # 抛出异常时把结果传进去 raise CustomException(result=resultIwant) return resultIwant
最后在bar函数中,从捕获的异常对象里取出结果:
def bar(): resultIwant = None try: resultIwant = foo() except CustomException as e: # 从异常中获取提前生成好的结果 resultIwant = e.result # 这里执行异常触发时的逻辑 finally: print(resultIwant) print('All done!')
方案二:在foo内部捕获异常标记,执行完代码后重新抛出
如果你的resultIwant必须在异常触发后才能生成(比如异常逻辑会影响结果),可以在foo内部先捕获异常,标记状态,执行完后续代码后再重新抛出异常:
def foo(): # good code exception_triggered = False try: if thingThatHappensSometimes: raise CustomException except CustomException: exception_triggered = True # 标记异常已触发 # code i want to execute:这里可以正常执行,不受之前的异常影响 resultIwant = 生成结果的代码() # 如果之前触发过异常,重新抛出并携带结果 if exception_triggered: raise CustomException(result=resultIwant) return resultIwant
bar函数的处理逻辑和方案一完全一致,这样既保证foo执行完所有代码生成结果,又能让bar的except块正常触发。
为什么原代码行不通?
你原来的foo函数中,raise CustomException会直接中断函数执行,后面的#code i want to execute和return resultIwant根本不会运行——这就是为什么你拿不到结果的原因。要么调整代码顺序让结果先生成,要么用内部捕获标记的方式确保后续代码执行,再传递异常和结果。
内容的提问来源于stack exchange,提问作者Josh Zwiebel
相关产品推荐
相关产品推荐

