没有括号的“ raise exception()”和“ raise exception”之间有区别吗?


99

定义无参数异常:

class MyException(Exception):
    pass

举起时,它们之间是否有任何区别:

raise MyException

raise MyException()

我找不到任何东西。它仅仅是一个重载的语法吗?



1
严格来说,这不是语法。Python直到运行时才知道它将获取类还是实例。
asmeurer 2014年

Answers:


114

简短的回答是,无论raise MyExceptionraise MyException()做同样的事情。第一种形式会自动实例化您的异常。

docs相关部分说:“ 抬高将第一个表达式评估为异常对象。它必须是BaseException的子类或实例。如果是类,则在需要时通过使用实例化该类来获取异常实例。没有争论。”

也就是说,即使语义相同,第一种形式在微观上也更快,而第二种形式则更灵活(因为如果需要,可以将其传递给参数)。

大多数人在Python中(即在标准库,流行的应用程序和许多书中)使用的通常样式是在raise MyException没有参数的情况下使用。人们仅在需要传递一些参数时才直接实例化异常。例如: raise KeyError(badkey)


18
为什么第一种形式(无括号)在显微镜下会更快?
jamesdlin

15
@jamesdlin因为自动实例化的C代码没有比您自己进行调用产生的解释开销。
Raymond Hettinger '18


0

是的,ValueError和之间有区别ValueError()

ValueError是一个类,而ValueError()创建一个类的实例。这就是原因type(ValueError) is typetype(ValueError()) is ValueError

的唯一目的raise是引发异常,

当我们使用时ValueError,将调用class,该class依次运行构造函数 ValueError()

当我们使用时ValueError(),该方法ValueError()被直接调用。

注意: raise ValueError # shorthand for 'raise ValueError()'

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.