【问题标题】:Python raise with two parametersPython raise 有两个参数
【发布时间】:2014-04-07 19:16:14
【问题描述】:

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

谢谢!

【问题讨论】:

    标签: python python-2.7 exception


    【解决方案1】:

    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 will unwrap nested tuples used as the first argument

    来自raise statement documentation

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

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

    【讨论】:

    • 感谢您的回答。你说raise Exception, e 就像raise Exception(e) 但我的例子表明它们是不同的。
    • @user3033336:对,因为你使用了e = E(),这是出乎意料的。
    • @user3033336:更新; Python 确实检测到您使用的值是异常的(子类)。
    • @user3033336:重写以更好地覆盖您的案例。
    • 所以对于raise A, B(c),规则是:if issubclass(A, BaseException) and isinstance(B(c), A): raise B(c); else: raise A(B(c))。我对吗?谢谢!
    猜你喜欢
    • 2021-04-18
    • 2020-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-29
    • 1970-01-01
    • 2014-12-13
    相关资源
    最近更新 更多