views:

222

answers:

6

I wonder if it is bad manner to skip return None, when it is not needed.

Example:

def foo1(x):
    if [some condition]:
        return Baz(x)
    else:
        return None

def foo2(x):
    if [some condition]:
        return Baz(x)

bar1 = foo1(x)
bar2 = foo2(x)

In both cases, when condition is false, function will return with None.

+3  A: 

Yes and No.

In the simplest case, it is ok to skip "return None" because it returns None in only single negative condition.

But if there are nested condition evaluation and multiple scenarios where a function could return None. I tend to include them as visual documentation of the scenarios.

[Editing: Based on comment below]

return or return None

I prefer "return None" to bare "return" as It is explicit and later, no one will be in doubt if the return meant returning None or was it an error as something was missing.

pyfunc
Even with nesting you could just use `return` instead of `return None`. Sometimes it can be clearer to make the `None` explicit, but often people use `None` to indicate some sort of exceptional case, in which case raising a well-named exception would be better.
adw
@adw : I agree with you. Some of these are style habits. I abhor using just "return" as if I had missed returning something. I prefer "return None" in such cases as I am explicit that this is what I wanted.
pyfunc
I personally do not use None for exceptional value but usually use it as place holder to indicate place for value. [] or () then indicate indefinite number of results and for some kind of functions they are better False-like value than return None (as None is not iterable)
Tony Veijalainen
+2  A: 

Yes, if you do not return any value from a Python function, it returns None. So, whether to explicitly return None is a stylistic decision.

Personally, I prefer to always return a value for clarity.

Alex JL
+12  A: 

Like you said, return None is (almost) never needed.

But you should consider that the intention of your code is much clearer with an explicit return None. Remember: a piece of code also needs to be readable by human-beings, and being explicit usually helps.

rsenna
Also helps to "comply" with `import this` :P
Nick T
What about at the end of an `__init__` method? Since you can't `return None`, is it better to have `return` or nothing at all?
dln385
@dln385: You can `return None` in `__init__`, in fact that's what `return` does.
adw
@dln385: I don't know if `__init__` is a *proper* constructor in Python, but it certainly works as one. So it should not return anything.
rsenna
Sorry, I must have been thinking about another language like Java. In Python, you can indeed `return None` in `__init__`. In fact, if you try to return a value, it says `TypeError: __init__() should return None`
dln385
"Explicit is better than implicit."
Davy8
From The Zen of Python http://www.python.org/dev/peps/pep-0020/
Davy8
and @Nick I just got it, +1 to your comment :p
Davy8
People parroting the "Zen of Python" make me constantly with for comment downvotes. Implicit is better than explicit when it's clearer and avoids needless redundancy.
Glenn Maynard
@dln385: Don't `return None` unless the None return value *itself* is meaningful. The return value of `__init__` is *not* meaningful, so don't explicitly return None. If you need to return from the middle of `__init__` just say `return`, and don't put an unnecessary `return` at the end of the function.
Glenn Maynard
@Glenn Maynard: so there's no need to be explicit, because there is no *intention* to return anything. I rest my case... :)
rsenna
+7  A: 

To expound on what others have said, I use a return None if the function is supposed to return a value. In Python, all function return a value, but often we write functions that only ever return None, because their return value is ignored. In some languages, these would be called procedures.

So if a function is supposed to return a value, then I make sure all code paths have a return, and that the return has a value, even if it is None.

If a function "doesn't" return a value, that is, if it is never called by someone using its return value, then it's ok to end without a return, and if I need to return early, I use the bare form, return.

Ned Batchelder
A: 
def foo1(x):
    try:
        return Baz(x)
    except:
        raise ValueError('Incorrect value fo Bac')

or

def foo3(x):
    return Baz(x) if <condition> else False

I do not believe in half defined function, but this False can be usefull in search type failure pruning.

Tony Veijalainen
+1  A: 

The more I think about it, the less I think the case you describe shows good practice. It forces the client to discriminate, so client code would almost always look like:

b = foo1(123)
if b is not None:
    ...

You couldn't even write:

if b:
    ...

since, if Baz.__nonzero__ is overwritten, b could evaluate to False, even if it's not None. It would be better to have a Null-Baz instance (AKA Null Object), e.g.:

class Baz(object):
    def some_method(self):
        """some action:"""
        ...
    ...

class BazNull(Baz):
    def some_method(self):
        """nothing happens here"""
    ...

Baz.Null = BazNull()

...

def foo1(x):
    if some_condition:
        return Baz(x)
    else:
        return Baz.Null

...

b = foo1(123)
b.some_method()

The point is: help the client (who might be yourself!) to keep Cyclomatic Complexity low. The fewer branches, the better.

pillmuncher
Good point. But in some cases I'm forced to return None. Ie. in Django Middleware you will return None in most of your methods.
Tomasz Wysocki