Python使用两个参数进行异常抛出

6

raise A, B的作用是触发异常A,并将B作为异常参数传递。而raise A则只是简单地触发异常A。

以下是一些例子(在Python 2.7解释器上运行):

class E(Exception):
    pass
e = E()

raise Exception, e
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
__main__.E

raise Exception(e)
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
Exception

raise (Exception, e)
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
Exception

谢谢!

1个回答

12

raise支持最多三个参数;前两个是类型和值,第三个是用于该异常的回溯对象。以下是代码示例:

raise Exception, value

通常情况下,这等同于:

raise Exception(value)

因此,创建一个Exception()的实例,将第二个值作为参数传递给异常构造函数。

然而,在您的示例中,第二个参数是E类型的实例,它是Exception的子类,因此这行代码:

raise Exception, e

相当于:

raise e

在这里您也可以使用一个空元组:

raise E, ()

或者None

raise E, None

只是为了增加不带参数引发 E 异常类型的方法数;元组第二个参数指定要用于 E 异常类型的所有参数;空元组或 None 只是使其等效于 raise E()

至于使用 元组 作为第一个参数,它相当于使用 raise Exception,因为Python 会展开用作第一个参数的嵌套元组

根据raise 语句文档

  

如果第一个对象是类,则它成为异常的类型。第二个对象用于确定异常值:如果它是类的实例,则该实例成为异常值。如果第二个对象是元组,则将其用作类构造函数的参数列表;如果是 None,则使用空参数列表,并且任何其他对象都被视为构造函数的单个参数。通过调用构造函数创建的实例用作异常值。

所有这些规则使语句变得过于复杂,有多种引发异常的方式在功能上是等效的。因此,在 Python 3 中,包含多个参数的 raise 语法已完全删除,请参见PEP 3109 - Raising Exceptions in Python 3000


1
谢谢您的回答。您说raise Exception, e就像raise Exception(e),但我的例子表明它们是不同的。 - user3033336
@user3033336:已更新;Python 确实会检测到您正在使用一个值,该值是 Exception 的子类。 - Martijn Pieters
@user3033336:重写以更好地涵盖您的情况。 - Martijn Pieters
那么对于 raise A, B(c),规则是:如果issubclass(A, BaseException)并且isinstance(B(c), A),则raise B(c);否则raise A(B(c))。我说得对吗?谢谢! - user3033336
@user3033336: if isinstance(B(c), A) 在这里已经足够了。 - Martijn Pieters
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接