13

I have a function that either returns a tuple or None. How is the Caller supposed to handle that condition?

def nontest():
  return None

x,y = nontest()

Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not iterable
2
  • 3
    The best option, if possible, is to change the called function so it will always return a tuple, possibly (None, None) Commented May 14, 2013 at 1:26
  • What do you want to do if the function returns None? What should x be in that case? What should y be in that case? Do you even really want to continue with the current calculation that uses x and y? Commented May 14, 2013 at 3:42

3 Answers 3

11

EAFP:

try:
    x,y = nontest()
except TypeError:
    # do the None-thing here or pass

or without try-except:

res = nontest()

if res is None:
    ....
else:
    x, y = res
Sign up to request clarification or add additional context in comments.

3 Comments

what about PEP 3132? is it relevant somehow?
I am not sure if you can assume (yet) that the OP means Python3.x if tagged Python.
Even for 3.x, I don't think it's relevant here. First, you'd have to write x, *y = nontest(), then if y is empty do the None-thing, otherwise do y = y[0], which I think isn't as clean as either of the two options. But, more importantly, x, *y = nontest() will still fail on None; you'd have to change nontest to return None,)` instead. At which point you might as well just return None, None and then you don't need extended unpacking.
8

How about:

x,y = nontest() or (None,None)

If nontest returns a two-item tuple like it should, then x and y are assigned to the items in the tuple. Otherwise, x and y are each assigned to none. Downside to this is that you can't run special code if nontest comes back empty (the above answers can help you if that is your goal). Upside is that it is clean and easy to read/maintain.

Comments

5

If you can change the function itself, it's probably a better idea to make it raise a relevant exception instead of returning None to signal an error condition. The caller should then just try/except that.

If the None isn't signalling an error condition, you'll want to rethink your semantics altogether.

4 Comments

Or, if it's perfectly appropriate to return nothing, you should probably be returning (None, None) or some other value that is a 2-tuple, instead of None.
Also, it's try/except, not try/catch.
@abarnert: you're right, of course. I haven't even touched Java in half a decade, but it still haunts me.
For me, it's C++, not Java… I think part of the problem is that there's no good verb for except. So where a Java/C++ user would say "try it, and catch the error", a Python user has to say "try it, and handle the error with an except". Since that's clumsy, we keep using "catch" as a verb, which means in non-code contexts it's easy to accidentally write try/catch.

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.