How a function hands a value back to its caller, and what you get when it doesn't.
Each call gets its own frame: a box holding that call's local variables. Calling pushes a frame on the stack.
return ends the call. Its value (pink) travels back to the line that made the call, and the frame is thrown away.
Each trace plays when you press →. Use ‹ ▶ › under the frames to step through it again.
# return single value
def square(x):
return x ** 2
result = square(5)
# ans: result is 25
# return multiple values (tuple)
def divide(a, b):
quotient = a // b
remainder = a % b
return quotient, remainder
q, r = divide(17, 5)
# ans: q=3, r=2
Python packs the two values into one tuple, and the assignment unpacks it.
# return exits function immediately
def is_even(n):
if n % 2 == 0:
return True
return False
result = is_even(4)
# ans: True
Line 5 never runs: the call is already over.
# function without return
def print_msg(msg):
print(msg)
result = print_msg("Hi")
# ans: Hi (printed)
# ans: result is None
Printing is not returning: falling off the end of a function returns None.
# return exits function and loop
def find_first_even(numbers):
for num in numbers:
if num % 2 == 0:
return num
result = find_first_even([1, 3, 4, 5])
# ans: 4
return leaves the loop and the function at once: 5 is never looked at.
Predict the result, then press → to run the code and check.
# what is returned?
def func():
x = 5
func()
# ans: None
# unpacking return values?
def func():
return 1, 2, 3
a, b, c = func()
# ans: a=1, b=2, c=3
# what happens?
def func():
return 1, 2, 3
x = func()
# ans: x is (1, 2, 3), a tuple
# early return?
def func(x):
if x > 5:
return "Big"
return "Small"
func(10)
# ans: "Big"
# return in else?
def func(x):
if x > 0:
return "Positive"
else:
return "Non-positive"
func(-5)
# ans: "Non-positive"
# multiple returns?
def func(x):
return x
return x + 1
func(5)
# ans: 5 (the second return is never reached)
# return nothing?
def func():
return
func()
# ans: None
# return in try?
def func():
try:
return 1
finally:
return 2
func()
# ans: 2 (finally overrides)
# conditional return?
def func(x):
if x:
return x * 2
func(0)
# ans: None (condition False, no return)
# return expression?
def func(a, b):
return a + b if a > b else a - b
func(5, 3)
# ans: 8
return ends the callNothing after it runs, not even the rest of a loop.
return a, b returns the tuple (a, b); unpack it with x, y = f().
A bare return, or reaching the end, gives None. Printing is not returning.
finally winsA return in finally replaces the one in try.