views:

154

answers:

4

Whats the difference between raising an exception and simply printing an error.

For example, whats the benefit of using the following:

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

instead of simply:

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

I'm a newbie, please take it easy on me. :)

+4  A: 

It depends if you can handle size < 0 at the point where size < 0 is detected.

If you can handle it by printing straight away, then print, otherwise, raise an exception, to delegate the handling of that condition to something further up the callstack, like this:

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"

In the (admittedly very contrived) example above, the divide_three_by function doesn't know what to do if you pass in 0 - sometimes you might just want to print a message (e.g. if val came from user input), sometimes you might want to just ignore it, and assign a default value. Since the function doesn't know what to do, it should pass responsibility for handling that condition up the callstack to whatever called it (and if it can't be handled there, it'll keep being passed up the callstack until something handles it, or until it reaches the top-level, at which point your program will terminate).

For more on handling exceptions in Python - take a look at the Errors and Exceptions tutorial in the Python documentation.

Dominic Rodger
I should probably point out that my example is *extremely contrived*, given the existence of `ZeroDivisionError` (http://docs.python.org/library/exceptions.html#exceptions.ZeroDivisionError)
Dominic Rodger
+6  A: 

Raising an error halts the entire program at that point (unless the exception is caught), whereas printing the message just writes something to stdout -- the output might be piped to another tool, or someone might not be running your application from the command line, and the print output may never be seen.

For example, what if your code is like:

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

and I call your script like:

yours.py number_source.txt | sum_all_lines.sh

If yours.py outputs plain text in between numbers, then maybe my sum_all_lines.sh will fail because it was expecting all numbers. However, if yours.py quits due to an exception, then sum_all_lines.sh will not finish, and it will be clear to me why the sum failed.

Of course, that's just one example, and your particular case may be completely different.

Mark Rushakoff
You omitted this: http://docs.python.org/reference/simple_stmts.html#the-raise-statement and http://docs.python.org/reference/simple_stmts.html#the-print-statement.
S.Lott
+2  A: 

The key difference is whether or not the program will continue to run after your error checking.

For this case:

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

This will just print the message to standard output and the program will continue past your check. So if at some point later in your code you uses size and it is less that 0 you may get an error.

For the other case:

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

In this case the program will not continue past your check, an exception will be raised. If it is not handled then the entire program will terminate.

Most of the time you will want to raise an exception and have an outer exception handler that catches the exception and tells the use about the error and if possible allows them to re-enter the input.

Tendayi Mawushe
+1  A: 

Another consideration is when developing a module that maybe used in other programs. In that case it is preferable to throw an exception and let the calling code handle the error. The caller should know that something went wrong and act accordingly.

...richie

Richie