Python:异常装饰器。如何保留堆栈跟踪

编程入门 行业动态 更新时间:2024-10-06 10:40:46
本文介绍了Python:异常装饰器。如何保留堆栈跟踪的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 我正在写一个装饰器来应用于一个功能。它应该捕获任何异常,然后根据原始异常消息引发自定义异常。 (这是因为suds抛出一个通用的WebFault异常,从该消息中我解析了Web服务引发的异常并引发了一个Python异常来反映它。)

然而,当我在包装器中引发自定义异常时,我希望stacktrace指向引发原始WebFault异常的函数。到目前为止,我已经提出了正确的异常(动态解析消息并实例化异常类)。 我的问题:如何保留堆栈跟踪指向引发WebFault异常的原始功能?

从functools导入包裹 def try_except(fn): def wrapped(* args,** kwargs): try: fn(* args, ** kwargs)除了异常,e: parser = exceptions.ExceptionParser() raise_exception = parser.get_raised_exception_class_name(e) exception = getattr(exceptions,raise_exception) raise exception(parser.get_message(e)) return wrap(fn)(wrapped)

解决方案

在Python 2.x中, raise 的一个鲜为人知的功能是可以使用不止一个参数: raise 的三参数形式接受异常类型,异常实例和追溯。您可以使用 sys.exc_info()获取回溯,该返回异常类型(异常实例和追溯)返回(不巧)。

(将异常类型和异常实例视为两个独立参数的原因是异常类之前的工件)。

所以:

import sys class MyError(Exception): pass def try_except(fn): def wrapped(* args,** kwargs): try: return fn(* args,** kwargs)除了异常,e: et,ei,tb = sys.exc_info() raise MyError,MyError(e),tb return wrapped def bottom ): 1/0 @try_except def middle(): bottom() def top(): middle() >>> top()追溯(最近的最后一次调用):文件< stdin>,第1行,< module> 文件tmp.py,第24行,顶部 middle()文件tmp.py,第10行,包装 return fn(* args,* * kwargs)文件tmp.py,第21行,中间 bottom()文件tmp.py,第17行,底部 1/0 __main __。MyError:整数除或模数为零

在Python 3中,这改变了一点。在那里,追溯附加到异常实例,而且它们有一个 with_traceback 方法:

raise MyError(e).with_traceback(tb)

另一方面Python 3也有例外链接,这在许多情况下更有意义;要使用它,您只需使用:

从e 中提取MyError(e)$ / code >

I am writing a decorator to apply to a function. It should catch any exception, and then raise a custom exception based on the original exception message. (This is because suds throws a generic WebFault exception, from whose message I parse the exception thrown by the web service and raise a Python exception to mirror it.)

However, when I raise the custom exception in the wrapper, I want the stacktrace to point to the function that raised the original WebFault exception. What I have so far raises the correct exception (it dynamically parses the message and instantiates the exception class). My question: How can I preserve the stacktrace to point to the original function that raised the WebFault exception?

from functools import wraps def try_except(fn): def wrapped(*args, **kwargs): try: fn(*args, **kwargs) except Exception, e: parser = exceptions.ExceptionParser() raised_exception = parser.get_raised_exception_class_name(e) exception = getattr(exceptions, raised_exception) raise exception(parser.get_message(e)) return wraps(fn)(wrapped)

解决方案

In Python 2.x, a little-known feature of raise is that it can be used with more than just one argument: the three-argument form of raise takes the exception type, the exception instance and the traceback. You can get at the traceback with sys.exc_info(), which returns (not coincidentally) the exception type, the exception instance and the traceback.

(The reason this treats the exception type and the exception instance as two separate arguments is an artifact from the days before exception classes.)

So:

import sys class MyError(Exception): pass def try_except(fn): def wrapped(*args, **kwargs): try: return fn(*args, **kwargs) except Exception, e: et, ei, tb = sys.exc_info() raise MyError, MyError(e), tb return wrapped def bottom(): 1 / 0 @try_except def middle(): bottom() def top(): middle() >>> top() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "tmp.py", line 24, in top middle() File "tmp.py", line 10, in wrapped return fn(*args, **kwargs) File "tmp.py", line 21, in middle bottom() File "tmp.py", line 17, in bottom 1 / 0 __main__.MyError: integer division or modulo by zero

In Python 3, this changed a little. There, the tracebacks are attached to the exception instance instead, and they have a with_traceback method:

raise MyError(e).with_traceback(tb)

On the other hand Python 3 also has exception chaining, which makes more sense in many cases; to use that, you would just use:

raise MyError(e) from e

更多推荐

Python:异常装饰器。如何保留堆栈跟踪

本文发布于:2023-11-12 20:57:56,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1582512.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:堆栈   异常   Python

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!