5

I see plenty of good advice about how to return multiple values in a function, but what's the preferred way to also handle checking other returns like False?

For example:

def f():
    if condition1:
        return False
    else:
        return x, y, z

x, y, z = f()

I can verify if [x, y, z] is not None: but how about also checking for False? Is it just if [x, y, z] is not None and f() is not False: or is there a superior way?

4
  • As far as I know, a function should always return the same object type (even if it is not required). Commented Dec 4, 2016 at 0:06
  • @ettanany No it should not. But it better does. Commented Dec 4, 2016 at 0:07
  • That's why I said "even if it is not required", In other programming languages you even mention the return value type in function definition. Commented Dec 4, 2016 at 0:09
  • 1
    @ettanany In general, this restriction wouldn't help. Suppose the OT function always returns a tuple: (False,) in the True case and x,y,z in the False case. Both tuples are "the same object type", but the original program still does not work, because the number of items is different. Commented Dec 4, 2016 at 0:12

3 Answers 3

12

I think it'd help to have more consistency:

def f():
    if condition1:
        return False, None
    else:
        return True, (x, y, z)

success, tup = f()
if success:
    x, y, z = tup
    # use x, y, z...
Sign up to request clarification or add additional context in comments.

Comments

9

If you are in the unfortunate situation where you must deal with a function that behaves like the one you presented, a clear way to handle it is with a try: statement.

try:
    x, y, z = f()
except TypeError:
    <handle the situation where False was returned>

This works because trying to unpack False raises a TypeError.


If you can modify the function, I might argue that the idiomatic strategy would be to raise an error (either built-in or custom) instead of returning False.

def f():
    if condition1:
        raise ValueError('Calling f() is invalid because condition1 evaluates to True')
    return x, y, z

try:
    x, y, z = f()
except ValueError:
    <handle the situation where a tuple could not be returned>

This has the benefit of showing the true nature of the error in an uncaught traceback rather than the less obvious TypeError: 'bool' object is not iterable. It also has the benefit of giving consistent return types, so there is no confusion from the user.

Documentation becomes much clearer as well, because instead of

"in the case of success it will return a tuple of three elements, but in the case of failure it will return False (not as a tuple)"

the documentation becomes

"returns a tuple of three elements; raises a ValueError on failure"

Comments

2

Assign the result to a single variable and check if it's false:

retval = f()
if retval != False:
  x,y,z = retval
else: # False
  ...

1 Comment

I downvoted because of the returning three Falses bit. It is redundant and may add complexity in a case when x, y, z each have meaningful boolean values.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.