[Tutor] functions: use return or exceptions?

Steven D'Aprano steve at pearwood.info
Fri Sep 24 03:35:28 CEST 2010


On Fri, 24 Sep 2010 05:32:55 am Alex Hall wrote:
> Hi all,
> A general coding question: is it better to use return(False) (or 0,
> or -1, or whatever) or to raise whateverError("oops")? Are there
> cases for each?

Yes.

There is absolutely no point whatsoever raising an exception, or 
returning a "magic" sentinel value, if an ordinary value would do. For 
example, this would be silly:


def is_spam(string):
    """Return True if string equals "spam", otherwise 
    raise an exception."""
    if string.lower().strip() == "spam":
        return True
    raise ValueError("not spam")


If is_spam can only ever return True, there's no need to look at the 
return result. So why bother to return anything? This would be better:

def verify_spam(string):
    """Raise ValueError unless string is spam."""
    if string.lower().strip() != "spam":
        raise ValueError("not spam")

(Technically, this will return None, but that's just because Python 
doesn't have procedures, only functions.)

This is appropriate if your use-case is something like this:

def prepare_meal(meat, condiments):
    """Prepare a yummy meal from the only meat-like substance 
    worth eating."""
    verify_spam(meat)
    if "pickle" in condiments:
        # I don't like pickle
        condiments.remove("pickle")
    # but I do like spam
    condiments.append("mashed spam")
    return "spam" + spread(condiments, meat) + "spam spam spam"


On the other hand, returning True or False would be better if your 
use-case was like this:

def prepare_meal(meat, condiments):
    """Prepare a yummy meal."""
    if is_spam(meat):
        vikings.sing("spam spam spam LOVELY SPAM!!!")
    if "pickle" in condiments:
        condiments.remove("pickle")
    return "bread" + spread(condiments, meat) + "bread"



A good guide is to look at what functions in the standard library do. 
You'll find examples of functions that return a magic value or raise an 
exception:

"ethel the aardvark".find('spam')
=> -1

"ethel the aardvark".index('spam')
=> raises exception

Of course, functions should generally raise exceptions for errors:

"ethel the aardvark".find(42)
=> raises exception

There are very few places in Python that suppress and hide arbitrary 
errors from the user. This should be done with care, if at all.


-- 
Steven D'Aprano


More information about the Tutor mailing list