python – return, return None, and no return at all?

python – return, return None, and no return at all?

On the actual behavior, there is no difference. They all return None and thats it. However, there is a time and place for all of these.
The following instructions are basically how the different methods should be used (or at least how I was taught they should be used), but they are not absolute rules so you can mix them up if you feel necessary to.

Using return None

This tells that the function is indeed meant to return a value for later use, and in this case it returns None. This value None can then be used elsewhere. return None is never used if there are no other possible return values from the function.

In the following example, we return persons mother if the person given is a human. If its not a human, we return None since the person doesnt have a mother (lets suppose its not an animal or something).

def get_mother(person):
    if is_human(person):
        return person.mother
    else:
        return None

Using return

This is used for the same reason as break in loops. The return value doesnt matter and you only want to exit the whole function. Its extremely useful in some places, even though you dont need it that often.

Weve got 15 prisoners and we know one of them has a knife. We loop through each prisoner one by one to check if they have a knife. If we hit the person with a knife, we can just exit the function because we know theres only one knife and no reason the check rest of the prisoners. If we dont find the prisoner with a knife, we raise an alert. This could be done in many different ways and using return is probably not even the best way, but its just an example to show how to use return for exiting a function.

def find_prisoner_with_knife(prisoners):
    for prisoner in prisoners:
        if knife in prisoner.items:
            prisoner.move_to_inquisition()
            return # no need to check rest of the prisoners nor raise an alert
    raise_alert()

Note: You should never do var = find_prisoner_with_knife(), since the return value is not meant to be caught.

Using no return at all

This will also return None, but that value is not meant to be used or caught. It simply means that the function ended successfully. Its basically the same as return in void functions in languages such as C++ or Java.

In the following example, we set persons mothers name and then the function exits after completing successfully.

def set_mother(person, mother):
    if is_human(person):
        person.mother = mother

Note: You should never do var = set_mother(my_person, my_mother), since the return value is not meant to be caught.

Yes, they are all the same.

We can review the interpreted machine code to confirm that that theyre all doing the exact same thing.

import dis

def f1():
  print Hello World
  return None

def f2():
  print Hello World
  return

def f3():
  print Hello World

dis.dis(f1)
    4   0 LOAD_CONST    1 (Hello World)
        3 PRINT_ITEM
        4 PRINT_NEWLINE

    5   5 LOAD_CONST    0 (None)
        8 RETURN_VALUE

dis.dis(f2)
    9   0 LOAD_CONST    1 (Hello World)
        3 PRINT_ITEM
        4 PRINT_NEWLINE

    10  5 LOAD_CONST    0 (None)
        8 RETURN_VALUE

dis.dis(f3)
    14  0 LOAD_CONST    1 (Hello World)
        3 PRINT_ITEM
        4 PRINT_NEWLINE            
        5 LOAD_CONST    0 (None)
        8 RETURN_VALUE      

python – return, return None, and no return at all?

They each return the same singleton None — There is no functional difference.

I think that it is reasonably idiomatic to leave off the return statement unless you need it to break out of the function early (in which case a bare return is more common), or return something other than None. It also makes sense and seems to be idiomatic to write return None when it is in a function that has another path that returns something other than None. Writing return None out explicitly is a visual cue to the reader that theres another branch which returns something more interesting (and that calling code will probably need to handle both types of return values).

Often in Python, functions which return None are used like void functions in C — Their purpose is generally to operate on the input arguments in place (unless youre using global data (shudders)). Returning None usually makes it more explicit that the arguments were mutated. This makes it a little more clear why it makes sense to leave off the return statement from a language conventions standpoint.

That said, if youre working in a code base that already has pre-set conventions around these things, Id definitely follow suit to help the code base stay uniform…

Leave a Reply

Your email address will not be published. Required fields are marked *