如何在装饰器中捕获异常,但是允许调用者也可以捕获它? [英] How do I catch an exception in a decorator but allow the caller to catch it as well?

查看:322
本文介绍了如何在装饰器中捕获异常,但是允许调用者也可以捕获它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个python函数可能引发异常。调用者捕获异常并处理它。现在我想添加一个装饰器到抓住异常,做一些处理,但是然后重新引发异常以允许原来的调用者来处理它。这是有效的,除了当原始的调用者从异常显示调用堆栈时,它显示在修饰器中重新生成的行,而不是最初发生的行。示例代码:

  import sys,traceback 

def mydec(func):
def dec():
try:
func()
除了异常,e:
打印'装饰器处理的异常%s'%e
raise e
return dec

@mydec
def myfunc():
x = $ 0

try:
myfunc()
除了异常,e:
print'异常:%s'%e
类型,值,tb = sys.exc_info()
traceback.print_tb(tb)
 装饰器处理异常整数除或模数为零
异常:整数除或模数为零
文件allbug.py,第20行,< module>
myfunc()
文件allbug.py,第9行,dec
raise e

我希望装饰器能够处理异常,但追溯应该指示 x = 1/0 行而不是 raise 行。我该怎么做?

解决方案

只需使用 raise; catch 块中不要提出任何具体的东西,只是 ),以重新提升异常而不需要重置追踪。


I have a python function that may raise an exception. The caller catches the exception and deals with it. Now I would like to add a decorator to that function that also catches the exception, does some handling, but then re-raises the exception to allow the original caller to handle it. This works, except that when the original caller displays the call stack from the exception, it shows the line in the decorator where it was re-raised, not where it originally occurred. Example code:

import sys,traceback

def mydec(func):
    def dec():
        try:
            func()
        except Exception,e:
            print 'Decorator handled exception %s' % e
            raise e
    return dec

@mydec
def myfunc():
    x = 1/0

try:
    myfunc()
except Exception,e:
    print 'Exception: %s' % e
    type,value,tb = sys.exc_info()
    traceback.print_tb(tb)

The output is:

Decorator handled exception integer division or modulo by zero
Exception: integer division or modulo by zero
  File "allbug.py", line 20, in <module>
    myfunc()
  File "allbug.py", line 9, in dec
    raise e

I would like the decorator to be able to handle the exception but the traceback should indicate the x = 1/0 line rather than the raise line. How can I do this?

解决方案

Just use raise; (i.e. do not raise anything specific, just raise;) in a catch block to re-raise the exception without "resetting" the traceback.

这篇关于如何在装饰器中捕获异常,但是允许调用者也可以捕获它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆