在Python中引发异常的正确方式是什么?

21

这是简单的代码:

import sys

class EmptyArgs(StandardError):
    pass

if __name__ == "__main__":
    # The first way to raise an exception
    if len(sys.argv) == 1:
       raise EmptyArgs
    # The second way to raise an exception
    if len(sys.argv) == 1:
       raise EmptyArgs()

哪种方式“更”正确?两种方式都可以工作。 提示:在我的真实代码中,异常与我声明的完全相同:没有消息和参数。

3个回答

30

两种方式都是正确的;后者可以让你将参数附加到异常上:

if len(sys.argv) == 1:
   raise EmptyArgs('Specify at least 1 argument')

请查看 raise语句 的文档。

Python 2有一些更多的选项,但这些选项已经从Python 3中删除。在Python 2中,您可以将异常类和参数作为元组传递,但Python 2现在已经不存在了。


2

不建议抛出没有参数的异常,即,抛出异常类并不是解决问题的方法。应该像这样做:

raise MyException()

由于在Python 3.0中,类似的情况已经被永久移除:
raise Exception, "foo"

应该有一种明显的方法来做它,最好只有一种。


(这句话是关于编程哲学的,强调代码应该简单明了,不应该存在多种复杂的解决方案。)

4
根据PEP 3109,在他的情况下没有区别,它说:“EXCEPTION可以是异常类或异常类的实例”。当您使用元组时(就像第二个示例中那样),问题就会发生。这不再有效。 - Paolo Moretti
1
@PaoloMoretti同意,但我仍然不建议这样做,就像我不建议使用制表符一样,希望它最终从Python 3.x中删除。 - Anurag Uniyal
你想要移除制表符吗?开玩笑的,我其实同意关于对象优先的说法;不过对于制表符的说法我不太同意。 - poke
@poke 对不起,我不是在谈论选项卡,而是在谈论引发异常类。 - Anurag Uniyal

1
这两种形式是等效的;它们最终都会抛出一个EmptyArgs实例。根据文档所述:

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

上述“第二个对象”是raise的(可选)第二个参数。
raise EmptyArgs, 'Invalid input!'

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