首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Python中的“内部异常”(带回溯)?

Python中的“内部异常”(带回溯)?
EN

Stack Overflow用户
提问于 2009-08-29 06:35:18
回答 9查看 48.6K关注 0票数 165

我的背景是C#,我最近才开始用Python语言编程。当抛出异常时,我通常希望将其包装在另一个添加更多信息的异常中,同时仍然显示完整的堆栈跟踪。这在C#中很简单,但是我该如何在Python中做到这一点呢?

例如:在C#中,我会这样做:

代码语言:javascript
复制
try
{
  ProcessFile(filePath);
}
catch (Exception ex)
{
  throw new ApplicationException("Failed to process file " + filePath, ex);
}

在Python中,我可以做类似的事情:

代码语言:javascript
复制
try:
  ProcessFile(filePath)
except Exception as e:
  raise Exception('Failed to process file ' + filePath, e)

...but这会丢失内部异常的回溯!

编辑:我希望同时看到异常消息和堆栈跟踪,并将两者关联起来。也就是说,我希望在输出中看到异常X出现在这里,然后异常Y出现在那里-与我在C#中一样。这在Python2.6中是可能的吗?看起来到目前为止(基于Glenn Maynard的答案)我能做的最好的事情是:

代码语言:javascript
复制
try:
  ProcessFile(filePath)
except Exception as e:
  raise Exception('Failed to process file' + filePath, e), None, sys.exc_info()[2]

这包括消息和回溯,但它不会显示回溯中的位置发生了哪个异常。

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2009-08-29 09:41:33

Python 2

这很简单;将回溯作为要引发的第三个参数传递。

代码语言:javascript
复制
import sys
class MyException(Exception): pass

try:
    raise TypeError("test")
except TypeError, e:
    raise MyException(), None, sys.exc_info()[2]

在捕获一个异常并重新引发另一个异常时,请始终执行此操作。

票数 141
EN

Stack Overflow用户

发布于 2011-06-06 06:42:06

Python 3

在python 3中,您可以执行以下操作:

代码语言:javascript
复制
try:
    raise MyExceptionToBeWrapped("I have twisted my ankle")

except MyExceptionToBeWrapped as e:

    raise MyWrapperException("I'm not in a good shape") from e

这将产生如下所示的结果:

代码语言:javascript
复制
   Traceback (most recent call last):
   ...
   MyExceptionToBeWrapped: ("I have twisted my ankle")

The above exception was the direct cause of the following exception:

   Traceback (most recent call last):
   ...
   MyWrapperException: ("I'm not in a good shape")
票数 290
EN

Stack Overflow用户

发布于 2012-10-23 03:33:05

Python3具有链异常的raise ... from clauseGlenn's answer对于Python2.7来说很棒,但它只使用了原始异常的回溯,并丢弃了错误消息和其他细节。以下是Python2.7中的一些示例,它们将来自当前作用域的上下文信息添加到原始异常的错误消息中,但保持其他细节不变。

已知的异常类型

代码语言:javascript
复制
try:
    sock_common = xmlrpclib.ServerProxy(rpc_url+'/common')
    self.user_id = sock_common.login(self.dbname, username, self.pwd)
except IOError:
    _, ex, traceback = sys.exc_info()
    message = "Connecting to '%s': %s." % (config['connection'],
                                           ex.strerror)
    raise IOError, (ex.errno, message), traceback

这种风格的raise statement将异常类型作为第一个表达式,将元组中的异常类构造函数参数作为第二个表达式,并将回溯作为第三个表达式。如果您运行的是早于Python2.2的版本,请参阅sys.exc_info()上的警告。

任何异常类型

这是另一个更通用的例子,如果你不知道你的代码可能需要捕捉什么类型的异常。缺点是它丢失了exception类型,只引发了一个RuntimeError。您必须导入traceback模块。

代码语言:javascript
复制
except Exception:
    extype, ex, tb = sys.exc_info()
    formatted = traceback.format_exception_only(extype, ex)[-1]
    message = "Importing row %d, %s" % (rownum, formatted)
    raise RuntimeError, message, tb

修改消息

如果异常类型允许您向其添加上下文,则还有另一种选择。您可以修改异常的消息,然后重新激活它。

代码语言:javascript
复制
import subprocess

try:
    final_args = ['lsx', '/home']
    s = subprocess.check_output(final_args)
except OSError as ex:
    ex.strerror += ' for command {}'.format(final_args)
    raise

这将生成以下堆栈跟踪:

代码语言:javascript
复制
Traceback (most recent call last):
  File "/mnt/data/don/workspace/scratch/scratch.py", line 5, in <module>
    s = subprocess.check_output(final_args)
  File "/usr/lib/python2.7/subprocess.py", line 566, in check_output
    process = Popen(stdout=PIPE, *popenargs, **kwargs)
  File "/usr/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1327, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory for command ['lsx', '/home']

您可以看到,它显示了调用check_output()的行,但是异常消息现在包括命令行。

票数 19
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1350671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档