return, return None, and no return at all?
On the actual behavior, there is no difference. They all return None
and that's 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 person
's mother
if the person
given is a human. If it's not a human, we return None
since the person
doesn't have a mother
(let's suppose it's 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 doesn't matter and you only want to exit the whole function. It's extremely useful in some places, even though you don't need it that often.
We've 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 there's only one knife and no reason the check rest of the prisoners
. If we don't 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 it's 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. It's basically the same as return
in void
functions in languages such as C++ or Java.
In the following example, we set person's mother's 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.
Type hint for return, return None, and no return at all?
They all should have the -> None
return type, since they all clearly return None
.
Note that there also exists the typing.NoReturn
type for functions that actually never return anything, e.g.
from typing import NoReturn
def raise_err() -> NoReturn:
raise AssertionError("oops an error")
Other types of functions (pointed out by @chepner) that actually never return and thus should be type hinted with -> NoReturn
would be for example an event loop that only ends using sys.exit
or any of the os.exec*
functions
Or should
my_func2
ormy_func3
have literally no return type hint?
In my opinion, they should always have a type hint, since as @yedpodtrzitko said in their answer, functions with no type hints are by default not type checked by mypy at all, and their return values are basically treated as if they would've been typed to be Any
. This greatly reduces the benefits of type checking, and that's one of the reasons I always use the mypy setting disallow_untyped_defs = True
for new projects.
Is there a way to return literally nothing in python?
There is no such thing as "returning nothing" in Python. Every function returns some value (unless it raises an exception). If no explicit return
statement is used, Python treats it as returning None
.
So, you need to think about what is most appropriate for your function. Either you should return None
(or some other sentinel value) and add appropriate logic to your calling code to detect this, or you should raise an exception (which the calling code can catch, if it wants to).
No return statement but not returning None?
From the comments:
Oh, so when they say functions will return None, I have to print None out to see it? Returning None doesn't mean None being shown on the output terminal?
Correct.
Is return none necessary if not used does it break the code?
In python, if you do not return anything, it will automatically (implicitly) return None
.
You can test that by making a function like
def fun():
pass
Then you can print the output of that function
print(fun())
And you will see that it will output None
. Thus, it is not a must to return None
.
Does python treat no return statement the exact same as return None?
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.
python - return returns None
You need to return again inside calculate_mathematical_expression
, e.g.:
def calculate_mathematical_expression(num1,num2,operation):
if operation == "+":
return mathematical_sum(num1,num2)
The return in mathematical_sum
doesn't affect the function it's being called from.
Related Topics
How to Get the Source Code of a Python Function
Can't Modify List Elements in a Loop
Explanation of How Nested List Comprehension Works
Should Import Statements Always Be At the Top of a Module
Why Are Python'S 'Private' Methods Not Actually Private
Performant Cartesian Product (Cross Join) With Pandas
Typeerror: a Bytes-Like Object Is Required, Not 'Str' When Writing to a File in Python 3
Haversine Formula in Python (Bearing and Distance Between Two Gps Points)
Remove All the Elements That Occur in One List from Another
Valueerror: Invalid Literal For Int() With Base 10: ''
How to Create a Text Input Box With Pygame
Equivalent of Shell 'Cd' Command to Change the Working Directory
Why Does Substring Slicing With Index Out of Range Work
Python Requests Throwing Sslerror
How to Get the Value of a Variable Given Its Name in a String