【发布时间】:2015-09-29 13:03:23
【问题描述】:
我调用外部程序并在失败时引发错误。问题是我无法捕获我的自定义异常。
from subprocess import Popen, PIPE
class MyCustomError(Exception):
def __init__(self, value): self.value = value
def __str__(self): return repr(self.value)
def call():
p = Popen(some_command, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()
if stderr is not '':
raise MyCustomError('Oops, something went wrong: ' + stderr)
try:
call()
except MyCustomError:
print 'This message is never displayed'
在这种情况下,python 打印 糟糕,出了点问题:[sderr 消息] 带有堆栈跟踪。
【问题讨论】:
-
代码按照您对我的期望工作。我注意到
self没有在if行中定义。另外,当子类化时,你通常也想调用父类的__init__。 -
您正在捕获异常,您的代码中没有错误,请添加堆栈跟踪。问题是发生了另一个您没有发现的异常。
-
旁注:不要这样做
if stderr is not '':;这依赖于巧合的对象身份测试,但不能保证。因为你知道它是一个str,而空的str是假的(而所有其他都是真的),你可以用if stderr:更简单/更有效地测试它。这会中断的示例:如果您迁移到 Python 3,则默认情况下来自communicate的返回是bytes,而不是str。b''将是一个无错误的完成,在if stderr:下会正常运行,但在if stderr is not '':下会正常运行。 -
单独的旁注:您的自定义错误正在执行
Exception将为您执行的操作(您只是给传递了错误名称的参数)。只需使用class MyCustomError(Exception): pass,它就可以正常工作(并且可以通过使用公共变量名与其他Exceptions 正确互操作);不需要多余的__init__或__str__定义。