Best practice in python for return value on error vs. success

First, whatever you do don't return a result and an error message. That's a really bad way to handle errors and will cause you endless headaches. If you need to indicate an error always raise an exception.

I usually tend to avoid raising errors unless it is necessary. In your example throwing an error is not really needed. Intersecting an empty list with a non empty one is not an error. The result is just empty list and that is correct. But let's say you want to handle other cases. For example if the method got a non-list type. In this case it is better to raise an exception. Exception are nothing to be afraid of.

My advice for you is to look at the Python library for similar functions and see how Python handles those special cases. For example have a look at the intersection method in set, it tends to be forgiving. Here I'm trying to intersect an empty set with an empty list:

>>> b = []
>>> a = set()
>>> a.intersection(b)
set([])

>>> b = [1, 2]
>>> a = set([1, 3])
>>> a.intersection(b)
set([1])

Errors are only thrown when needed:

>>> b = 1
>>> a.intersection(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable

Sure, there are cases where returning True or False on success or failure can be good. But it is very important to be consistent. The function should always return the same type or structure. It is very confusing to have a function that could return a list or a boolean. Or return the same type but the meaning of this value can be different in case of an error.

EDIT:

The OP says:

I want to return something to indicate the parameters were incorrect.

Nothing says there is an error better than an exception. If you want to indicate the parameters are incorrect then use exceptions and put a helpful error message. Returning a result in this case is just confusing. There might other cases where you want to indicate that nothing has happened but it is not an error. For example if you have a method that deletes entries from a table and the entry requested for deletion does not exist. In this case it might be fine to just return True or False on success or failure. It depends on the application and the intended behaviour


It'd be better to raise an exception than return a special value. This is exactly what exceptions were designed for, to replace error codes with a more robust and structured error-handling mechanism.

class IntersectException(Exception):
    def __init__(self, msg):
        self.msg = msg
    def __str__(self):
        return self.msg

def intersect_two_lists(self, list1, list2):
    if not list1: raise IntersectException("list1 must not be empty.")
    if not list2: raise IntersectException("list2 must not be empty.")

    #http://bytes.com/topic/python/answers/19083-standard
    return filter(lambda x:x in list1,list2)

In this specific case though I'd probably just drop the tests. There's nothing wrong with intersecting empty lists, really. Also lambda is sort of discouraged these days in preference to list comprehensions. See Find intersection of two lists? for a couple of ways to write this without using lambda.


I like to return a tuple:

(True, some_result)

(False, some_useful_response)

The some_useful_response object can be used for handling the return condition or can serve to display debugging info.

NOTE: this technique applies for return values of any sort. It should not be mistaken with exception cases.

On the receiving end, you just have to unpack:

Code, Response = some_function(...)

This technique applies for the "normal" control flow: one must use the exception functionality when some unexpected inputs / processing occur.

Also worth noting: this technique helps normalizing function returns. Both the programmer and the user of the functions know what to expect.

DISCLAIMER: I come from an Erlang background :-)