Reputation: 3768
Often you want to use None
as a return value for functions. Is there a Python idiom to avoid calling a function two times if you want either do one thing if the function returns None
and if not use the result of the function. Below is a silly example.
def foo(a, b):
if b == 0:
return(None)
else:
return(a/b)
a = b = 2
if foo(a, b) is None: #Do one thing. 1st call to function.
print('b cannot be null')
else: #Use the result of function. 2nd function call.
print('The result is: ' + str(foo(a,b)) )
Is this stateful way the alternative (with only one function call, but need to assign result, which could be huge, to a variable) ?:
res = foo(a, b)
if res is not None:
print('The result is: ' + str(res) )
else:
print('b cannot be null')
Upvotes: 3
Views: 601
Reputation: 24232
In your example, foo returns None
to mean: "Something in the parameters is wrong, and I can't return a valid value".
In that case, it would be clearer to use an exception:
def foo(a, b):
if b == 0:
raise ValueError("b can't be zero")
else:
return a/b
So, if b is null, foo won't return anything - and you won't have to test the return value to check if it's valid, or if it means "something wrong happened". If foo returns something, you're certain that it is a valid result.
Now, to use foo, you would use a try
... except
block:
a = 2
b = 0
try:
print('The result is: ' + str(foo(a,b)) )
except ValueError as msg:
print(msg)
# b can't be zero
If you don't put the call to foo
in such a block, your program will stop with a nice, informative error message:
foo(a, b)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-36-89e9686ab4be> in <module>()
14 print(msg)
15
---> 16 foo(a, b)
<ipython-input-36-89e9686ab4be> in foo(a, b)
1 def foo(a, b):
2 if b == 0:
----> 3 raise ValueError("b can't be zero")
4 else:
5 return a/b
ValueError: b can't be zero
which is also good, because your program should fail immediately when something goes wrong.
Upvotes: 2