Consider this code:
def foo(foo_input):
if 0 <= foo_input <= 100:
return f_input
This returns None in the case where foo_input > 100. But could it actually not return anything? Or does a function always have to return something?
Consider this code:
def foo(foo_input):
if 0 <= foo_input <= 100:
return f_input
This returns None in the case where foo_input > 100. But could it actually not return anything? Or does a function always have to return something?
Functions always return something (at least None, when no return-statement was reached during execution and the end of the function is reached).
Another case is when they are interrupted by exceptions.
In this case exception handling will "dominate over the stack" and you will return to the appropriate except or get some nasty error :)
Regarding your problem I must say there are two possibilities: Either you have something to return or you do not have.
None will tell the caller that this was the case (
There is no better way to tell the caller that "nothing" is returned then by None, so check for it and you will be fine)I'm not sure what you really are trying to do. Here are a few things you might like:
def foo(foo_input, foo_default):
if 0 <= foo_input <= 100:
return f_input
else:
return foo_default
def foo(foo_input):
if 0 <= foo_input <= 100:
return f_input
raise ValueError, "foo_input was not in range [0, 100]"
Wait, you said "filter". Are you filtering a series of values and you just want to extract the ones that meet a criteria? That's easy in Python:
def foo_check(x):
return 0 <= x <= 100
filtered_list = [x for x in unfiltered_sequence if foo_check(x)]
And you said "chaining functions". Again that's easy if we are talking about filtering a sequence:
def foo_filter(seq):
for x in seq:
if 0 <= x <= 100:
yield x
def other_filter(seq):
for x in seq:
if meets_criterion(x):
yield x
def do_the_task(seq):
for x in other_filter(foo_filter(seq)):
do_something(x)
EDIT: Here is a nice introduction to iterators and generators in Python. http://www.learningpython.com/2009/02/23/iterators-iterables-and-generators-oh-my/
[x for x in sequence if 0 <= x <= 100].filter function? filtered_list = filter(foo_filter, unfiltered_sequence)>>> prompt type help(filter) and read what it says. It says, quite plainly, that it will return a list, a tuple, or a string. Now fire up Python 3.x and do the same thing; it says, quite plainly, that it will return an iterator. So maybe you don't see why it should do it, but I am talking about what it actually does. I think the reason is historical: I think filter() was introduced before iterators were added. Of course in Python 2.x you can use itertools.ifilter() or write your own function that loops and calls yield.I sort of like the implicit return None but pylint flags it as bad style, warning:
Either all return statements in a function should return an expression, or none of them should.pylint(inconsistent-return-statements)
Hence,
def foo(foo_input):
if 0 <= foo_input <= 100:
return f_input
return None
might be better style, even if they are functionally the same.
More info available here, where the Pylint change-log states:
A new Python checker was added to warn about inconsistent-return-statements. A function or a method has inconsistent return statements if it returns both explicit and implicit values ...
According to PEP8, if any return statement returns an expression, any return statements where no value is returned should explicitly state this as return None, and an explicit return statement should be present at the end of the function (if reachable).
None?None- although if it's more likely you will get a result than None, catching exceptions is a better idea, as Python follows the ask for forgiveness, not permission principle.Noneanywhere in your process, then you can simply wrap your entire block in a catch forTypeErrors. Obviously only wrap the segment for which this is necessary, but there is no need for a ton of the sametry ... except ...blocks