2010-01-27 74 views
8

引发异常和简单打印错误有什么区别。引发异常与打印?

例如,什么使用以下的好处:

if size < 0: 
     raise ValueError('number must be non-negative') 

简单地代替:

if size < 0: 
     print 'number must be non-negative' 

我是一个新手,请把我很容易。 :)

+3

当您尝试此代码时,您观察到了什么差异? – 2010-01-27 12:27:47

回答

8

Raising an error在该点停止整个程序(除非异常被捕获),而printing消息只是写东西stdout - 输出可能被管道输送到另一个工具,或者有人可能无法运行从应用程序命令行,并且print输出可能永远不会被看到。

例如,如果你的代码是什么样子:

if size < 0: 
    print 'size must be non-negative' 
else: 
    print size * 4 

,我打电话给你的脚本,如:

yours.py number_source.txt | sum_all_lines.sh

如果yours.py输出数字之间的纯文本,那么也许我的sum_all_lines.sh将失败,因为它期待所有数字。但是,如果yours.py由于例外而退出,那么sum_all_lines.sh不会完成,并且我将清楚为什么该总和失败。

当然,这只是一个例子,您的具体情况可能会完全不同。

+2

您省略了这个:http: //docs.python.org/reference/simple_stmts.html#the-raise-statement和http://docs.python.org/reference/simple_stmts.html#the-print-statement。 – 2010-01-27 12:27:22

6

这取决于您是否可以在检测到size < 0的位置处理size < 0

如果您可以通过印刷直线距离,然后print处理它,否则,引发异常,委托该条件的处理的东西进一步向上调用堆栈,像这样:

def divide_three_by(val): 
    if val == 0: 
    raise ValueError("Can't divide by 0") 
    return 3/val 

try: 
    divide_three_by(some_value_from_user) 
except ValueError: 
    print "You gave stupid input" 

在(上面的例子中,divide_three_by函数不知道如果你传入0时该怎么做 - 有时候你可能只是想打印一条消息(例如,如果val来自用户输入),有时候你可能只想忽略它,并分配一个默认值。由于函数不知道该怎么做,它应该将处理这个条件的责任传递给调用堆栈的任何东西(如果它不能在那里处理,它将继续传递给堆栈,直到处理它,或者直到它到达顶层,此时程序将终止)。

有关在Python中处理异常的更多信息,请参阅Python文档中的Errors and Exceptions tutorial

+0

我应该指出,我的例子*非常人为*,因为存在'ZeroDivisionError'(http://docs.python.org/library/exceptions.html#exceptions.ZeroDivisionError) – 2010-01-27 12:38:52

2

关键的区别在于程序是否会在错误检查后继续运行。

对于这种情况:

if size < 0: 
    print 'number must be non-negative' 

这将只打印信息到标准输出,并计划将继续以往的检查。因此,如果在某一点在后面的代码你使用size,它是小于0你可能会得到一个错误。

对于其他情况:

if size < 0: 
    raise ValueError('number must be non-negative' 

在这种情况下,程序将不会继续过去的检查中,将引发异常。如果不处理,则整个程序将终止。

大多数时候,你会想抛出异常,并有捕捉异常,并讲述了错误的使用外异常处理程序的时间,如果可能的话让他们重新进入输入法。

3

另一个考虑因素是开发在其他程序中可能使用的模块时。在这种情况下,最好抛出异常并让调用代码处理错误。来电者应该知道出现了问题,并据此采取行动。

... richie