Python中使用两个参数的raise

7 投票
1 回答
9787 浏览
提问于 2025-04-18 01:45

raise A, B 是做什么的?它和 raise 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 类型的一个实例,而 EException 的一个子类,因此这一行:

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 - 在 Python 3000 中抛出异常

撰写回答