Don't call function if None Value returned

reox picture reox · Jan 24, 2014 · Viewed 7.5k times · Source

suppose you have a function that can return some object or None:

def foobar(arg):
   if arg == 'foo':
       return None
   else:
       return 'bar'

Now you call this method and you want to do something with the object, for this example i get a str, so i may want to call the upper() function. There are now two cases that can happen, where the second one will fail, because None has no method upper()

foobar('sdfsdgf').upper()
foobar('foo').upper() 

of course this is now easy to fix:

tmp = foobar('foo')
if tmp is not None:
    tmp.upper()
# or
try:
    foobar('foo').upper()
except ArgumentError:
    pass
# or
caller = lambda x: x.upper() if type(x) is str else None
caller(foobar('foo'))

but the exception handling is maybe not specfic enough and it can happen that i catch an exception that could be important (= debugging gets harder), while the first method is good but can result in larger code and the third option looks quite nice but you have to do it for all possible functions so method one is probably the best.

I wonder if there is any syntactic sugar that handle this problem nicely?

Answer

Martijn Pieters picture Martijn Pieters · Jan 24, 2014

You can use:

(foobar('foo') or '').upper()

The expression inside the parenthesis returns a string, even if foobar() returns a falsy value.

This does result in None being replaced by the empty string. If your code relies on None being left in place, your best choice still is to use a separate if statement to call .upper() only if the return value is not None.