Search code examples
pythonreturnpython-internals

Does python treat no return statement the exact same as return None?


Code:

def foo():
    if condition:
        return some_value
    return None

def bar():
    if condition:
        return some_value

Both of these return None if condition is false, but do they vary in terms of computation time or anything else? Which one is generally preferred


Solution

  • In current versions of CPython, return None is exactly the same as not returning at all. Both are compiled into two bytecodes, a LOAD_CONST bytecode (to load None) and a RETURN_VALUE (to do the return).

    You can see this by disassembling the two functions you've written, using the dis module:

    >>> import dis
    >>> dis.dis(foo)
      2           0 LOAD_GLOBAL              0 (condition)
                  2 POP_JUMP_IF_FALSE        8
    
      4           4 LOAD_GLOBAL              1 (some_value)
                  6 RETURN_VALUE
    
      5     >>    8 LOAD_CONST               0 (None)
                 10 RETURN_VALUE
    
    >>> dis.dis(bar)
      8           0 LOAD_GLOBAL              0 (condition)
                  2 POP_JUMP_IF_FALSE        8
    
     10           4 LOAD_GLOBAL              1 (some_value)
                  6 RETURN_VALUE
            >>    8 LOAD_CONST               0 (None)
                 10 RETURN_VALUE
    

    The only difference is that bar has fewer lines (indicated in the first column), since the implicit return doesn't correspond to any line in the source code.

    The fact that they're identical is, however, an implementation detail. It's possible that other Python interpreters, perhaps even including other versions of CPython could produce different code for the two situations.

    And even if the implementation is the same, an explicit return None may make it much more clear to somebody reading the code that you care about the return value. Relying upon the implicit return value suggests that you do not care about the return value, and that the function is primarily called for its side effects (e.g. printing something, or mutating some object in place).

    And the person reading your code might be you in the future, after you've forgotten exactly how you programmed this function. Writing code that is clear about what it is doing is often even harder than writing code that compiles and runs correctly.