Parameters let data flow into a function. The return statement lets data flow out. Together, parameters and return values make a function a complete, self-contained unit of computation: data enters through the parameters, the function processes it, and the result exits through the return value. This input-processing-output model is the same model that governs mathematical functions, Unix command-line tools, and the request-response cycle of web servers. Once you internalize it, you can think about any function in terms of what it needs and what it produces, without caring about the details inside.
The return statement does two things simultaneously. It specifies the value that the function sends back to its caller, and it immediately ends the function's execution. Any code written after a return statement on the same indentation level will never run, because the return has already handed control back to the caller. Python does not warn you about unreachable code after a return, but linters and code editors typically flag it with a visual indicator, and you should treat those indicators as errors to fix.
If you have been following this learning path, you have already seen return values in action with functions like len and input. When you write name = input("What is your name? "), the input function returns the string the user typed, and that return value is stored in the variable name. When you write if len(password) >= 8, the len function returns an integer, and that integer is compared to 8. Every useful computation your program performs depends on functions returning values that other parts of the program can use.
The basic return statement
The simplest form of return is followed by a value or an expression. Python evaluates the expression, produces a value, and sends that value back to the caller:
def add(a, b):
return a + b
result = add(3, 7)
print(result)The add function receives two numbers through its parameters, adds them together, and returns the sum. The caller captures the return value in the variable result and can then use it for further computation or display. The key insight is that a function call like add(3, 7) becomes the value 10 in the expression where it is called. You can use it anywhere a value is expected, including as part of a larger expression.
This composability, the ability to use a function call as part of a larger expression, is what makes return values powerful. A function that returns a boolean can be used directly in an if condition. A function that returns a string can be passed to print without an intermediate variable. A function that returns a list can be looped over with for. The return value type determines how the function can be composed with other code.
Functions that return nothing
A function without a return statement still completes and hands control back to the caller, but it sends back no value. In Python, "no value" is represented by the None object, so a function that does not explicitly return anything implicitly returns None. Functions that exist solely for their side effects, such as printing output, writing to a file, or updating a database, are common and legitimate. Returning None from them is the correct Python convention.
The distinction between functions that return values and functions that produce side effects becomes important when you start testing your code. A pure function that computes a return value from its parameters without any side effects is trivial to test: call it with known inputs and assert that the return value matches your expectation. A function with side effects requires more setup; you may need to create temporary files, mock network calls, or capture printed output to verify that the side effects happened correctly.
Returning multiple values
Python functions can appear to return multiple values by separating them with commas after the return keyword. What actually happens under the hood is that Python packs the values into a tuple and returns the tuple as a single object:
def min_max(numbers):
return min(numbers), max(numbers)
lowest, highest = min_max([4, 1, 9, 3])The return line creates a tuple containing the minimum and maximum values and returns it. The caller unpacks the tuple into the variables lowest and highest using multiple assignment. If the caller does not unpack the tuple, the return value is a single tuple object that can be indexed or iterated like any other tuple. This pattern eliminates the need for output parameters or wrapper objects in simple cases and is widely used throughout Python codebases.
Returning early with guard clauses
The return statement immediately exits the function, which means you can use it at the top of a function to handle edge cases before the main logic runs. This pattern is called a guard clause, and it improves readability by eliminating nested indentation:
def divide(a, b):
if b == 0:
return None
return a / bWithout the guard clause, you would need to wrap the division in an else block, pushing the main logic deeper into indentation. The guard clause handles the edge case up front and exits, making the function's contract explicit. A caller reading this function can see from the first line of the body that it returns None when the divisor is zero, which tells the caller to check for None before using the result.
Return versus print confusion
The most common point of confusion for beginners learning about return values is the difference between returning and printing. A function that uses print displays output in the terminal. A function that uses return sends a value back to the code that called it. These are fundamentally different operations, and confusing them leads to programs that display the correct output but cannot use that output for further computation.
A function that computes a value but uses print instead of return will display the value on screen, but the variable that captures the call result will be None. If you later try to use that variable in a calculation, you will get a TypeError when Python tries to operate on None. A function that uses return produces no visible output when called, but the return value is available for any subsequent computation. The best practice is to keep these concerns separate: let functions compute and return, and let the caller decide whether to print the result.
Rune AI
Key Insights
- The return statement sends a value from the function back to the caller and immediately ends the function's execution.
- A function without a return statement returns None implicitly; this is correct behavior for functions that act through side effects.
- Returning multiple values separated by commas actually returns a tuple, which the caller can unpack into separate variables.
- Return values let functions be composed: the output of one function becomes the input to another.
- Avoid mixing return and print in the same function; a function should either compute and return or display and print, not both.
Frequently Asked Questions
What is the difference between return and print in a Python function?
Can a Python function return more than one value?
What does a Python function return if there is no return statement?
Conclusion
The return statement is how functions communicate results back to the code that called them. A function that returns can feed its output into other functions, be tested in isolation, and participate in expressions. Understanding the distinction between returning and printing, and knowing how None and multiple return values work, gives you full control over the flow of data through your programs.
More in this topic
Define and Call Python Functions
Learn the exact syntax for defining and calling Python functions with the def keyword, including naming rules, the function body, and how the call stack works.
Python Function Parameters and Arguments
Learn the difference between parameters and arguments, how to pass values by position and by keyword, and the rules for default parameter values.
Python Functions Explained
Learn what Python functions are, why they matter for organizing code, and how they form the foundation of non-trivial programs.