Function Return in Python: A Comprehensive Guide
The Python return Statement: Usage and Best Practices
The Python return
statement is a key component of functions and methods. It allows you to send Python objects back to the caller code, known as the function’s return value. Understanding how to use the return
statement effectively is crucial in writing Pythonic and robust functions.
In this tutorial, you will learn:
1. How to use the Python return
statement in your functions:
- Explicit return Statements
- Implicit return Statements
2. Returning vs Printing
3. Returning Multiple Values
4. Best Practices for Using the Python return
Statement:
- Returning None Explicitly
- Remembering the Return Value
- Avoiding Complex Expressions
- Returning Values vs Modifying Globals
- Using return With Conditionals
- Returning True or False
- Short-Circuiting Loops
- Recognizing Dead Code
- Returning Multiple Named-Objects
5. Returning Functions: Closures
6. Taking and Returning Functions: Decorators
7. Returning User-Defined Objects: The Factory Pattern
8. Using return
in try … finally Blocks
9. Using return
in Generator Functions
10. Conclusion
To help you understand these concepts better, this tutorial provides detailed explanations and includes step-by-step sample code that you can run and experiment with.
Getting Started With Python Functions
Before diving into the specifics of the return
statement, it’s important to familiarize yourself with how functions work in Python. Functions allow you to assign a name to a code block that performs a specific computation and can be reused throughout your code. These named code blocks are commonly referred to as subroutines, routines, procedures, or functions.
To call a function, you simply use its name followed by parentheses. For example:
Output:
In the example above, we defined a function called say_hello()
that prints “Hello, world!“. When we call the function using say_hello()
, the code inside the function is executed, resulting in the output “Hello, world!“.
Understanding the Python return
Statement
Now let’s dive into the specifics of the Python return
statement. The return
statement allows you to specify the value or values that should be sent back to the caller code.
Explicit return Statements
To explicitly return a value from a function, you use the return
keyword followed by the value you want to return. Here’s an example:
Output:
In the example above, the add_numbers()
function takes two arguments, a
and b
, and returns the sum of the two numbers. The returned value is then stored in the result
variable and printed to the console.
Implicit return Statements
If a function doesn’t have an explicit return
statement, it will implicitly return None
, which serves as a placeholder for the absence of a value. Here’s an example:
Output:
In this example, the say_hello()
function doesn’t have a return
statement. As a result, it implicitly returns None
. When we assign the result of calling say_hello()
to the variable result
and print it, we see that None
is returned.
Returning vs Printing
It’s important to understand the difference between returning a value from a function and printing a value within a function.
Returning a value allows you to use the result of a function in further computations or assign it to a variable, while printing a value within a function simply displays it on the console but doesn’t make it available for further use.
For example:
Output:
In this example, the square()
function returns the square of the number
argument. The returned value is then stored in the result
variable and printed to the console.
If we were to print the square value directly within the function instead of returning it, we wouldn’t be able to use it outside the function:
Output:
In this modified example, the square()
function prints the square of the number
argument directly. When we call square(3)
, the square value of 9 is printed to the console. However, since there is no return
statement, we cannot capture the square value for further computations or assign it to a variable.
So, the choice between returning a value or printing a value within a function depends on whether you need to use the result in subsequent code or simply display it on the console.
Returning Multiple Values
Python allows you to return multiple values from a function by separating them with commas. This feature is often used to conveniently pack and unpack related values. Here’s an example:
Output:
In this example, the get_name_and_age()
function returns the name
and age
as a tuple. When we call get_name_and_age()
and assign the result to the person
variable, we get a tuple with both values. We can access each value using indexing, as demonstrated by printing person[0]
and person[1]
.
You can also directly assign the returned values to separate variables using tuple unpacking:
Output:
In this modified example, the returned values are assigned to the name
and age
variables directly. This allows us to access and use each value individually.
Returning multiple values is a powerful feature that allows you to group related data together and easily work with it in your code.
Using the Python return Statement: Best Practices
When using the return
statement in your functions, it’s important to follow best practices to ensure your code is clear, maintainable, and efficient. Here are some best practices to keep in mind:
Returning None Explicitly
If a function doesn’t have a meaningful value to return, it’s good practice to explicitly return None
instead of relying on implicit return statements. This makes the code more self-explanatory and avoids any potential confusion. Here’s an example:
Output:
In this example, the log_message()
function prints the message
if it has a length greater than 0. Otherwise, it explicitly returns None
to indicate that no meaningful value is being returned. When we print the result of calling log_message("Hello, world!")
, we see the message being printed and None
being returned.
Remembering the Return Value
When calling a function that returns a value, it’s good practice to assign the returned value to a variable for future use or further computations. This makes your code more readable and allows you to easily refer back to the returned value without re-executing the function. Here’s an example:
Output:
In this example, the calculate_average()
function takes a list of numbers
and calculates the average grade. The returned average value is then assigned to the average_grade
variable, making it easier to refer back to the result.
Avoiding Complex Expressions
When using the return
statement, it’s generally considered best practice to avoid including complex expressions or calculations within the return
statement itself. Instead, break down the calculation into smaller steps to improve code readability and maintainability. Here’s an example:
Output:
In this example, the calculate_discounted_price()
function calculates the discounted price of a product based on the original price and a discount rate. By breaking down the calculation into separate steps within the function, the return
statement is kept simple and easier to understand.
Returning Values vs Modifying Globals
In general, it’s recommended to design your functions to return values instead of directly modifying global variables. This helps to encapsulate functionality and makes your code more modular and reusable.
Returning values allows you to control how the function’s result is used without affecting other parts of your code. It also makes it easier to test and debug your functions since their behavior is isolated and predictable.
Output:
In this example, the greet()
function modifies the global name
variable to “Bob” instead of returning a value. While this code works, it’s generally considered better practice to have the function return a value and have the caller code decide how to use that value:
Output:
In this modified example, the get_greeting()
function returns the greeting as a string. The caller code then decides how to use that returned value, which leads to more flexible and modular code.
Using return
With Conditionals
Often, you may need to use conditional statements within your functions to handle different cases or scenarios. In these situations, it’s good practice to have a single return
statement at the end of the function to ensure a consistent and predictable flow of execution. Here’s an example:
Output:
In this example, the get_grade()
function takes a score
parameter and returns the corresponding grade based on a series of conditional statements. By having a single return
statement at the end of the function, we ensure that only one value is returned and that the flow of execution is clear.
Returning True or False
Sometimes, you may want to write functions that return a Boolean value (True
or False
) based on certain conditions. In these cases, it’s good practice to have the function return the appropriate Boolean value directly, without using conditional statements. Here’s an example:
Output:
In this example, the is_even()
function takes a number
as input and directly returns True
or False
based on whether the number is even or not. By returning the Boolean value directly, we avoid unnecessary use of conditional statements and make the function’s behavior more explicit.
Short-Circuiting Loops
When using loops in your functions, it’s good practice to use the return
statement to exit the loop prematurely if a certain condition is met. This is known as short-circuiting the loop and can help improve performance and reduce unnecessary computations. Here’s an example:
Output:
In this example, the find_number()
function takes a list of numbers
and a target
number. It loops through the list and returns True
as soon as it finds a number that matches the target. If no match is found, it returns False
. By short-circuiting the loop, we avoid unnecessary iterations and end the function as soon as the target is found.
Recognizing Dead Code
When using the return
statement, it’s important to be aware of any dead code that appears after the return
statement. Dead code refers to any code that is written but never executed due to an earlier return
statement. Keeping your code clean and free of dead code helps improve readability and maintainability. Here’s an example:
Output:
In this example, the is_positive()
function returns True
if the number
is greater than 0 and False
otherwise. The print()
statement that follows the return
statement is considered dead code because it is never executed. Removing this dead code improves the clarity and efficiency of the function.
Returning Multiple Named-Objects
In addition to returning multiple values as tuples, you can also return multiple named objects using techniques such as dictionaries or classes. This allows you to provide more descriptive names for the returned values and improves code readability. Here’s an example using a dictionary:
Output:
In this example, the get_person_info()
function returns a dictionary with information about a person. By returning a dictionary, we can access each piece of information using descriptive keys, making the code more readable and organized.
Conclusion
The Python return
statement is a powerful tool for sending values back to the caller code from functions. By understanding how to use the return
statement effectively, you can write more readable, maintainable, and efficient code.
In this tutorial, you learned about the different aspects of the return
statement, including explicit and implicit return statements, returning vs printing, returning multiple values, and best practices for using the return
statement. Armed with this knowledge, you can enhance your Python programming skills and create better functions that make your code more streamlined and effective.