Passing by Reference in Python: Explained
Pass by Reference in Python: Background and Best Practices
by Marius Mogyorosi
Defining Pass by Reference
Before diving into the technical details of passing by reference in Python, let’s understand the concept:
- Pass means providing an argument to a function.
- By reference means passing a reference to an existing variable to the function instead of an independent copy of the variable.
In Python, all function arguments are passed by reference, but the behavior might differ from what you expect if you are familiar with other programming languages. In Python, function arguments behave as references to objects in memory.
Contrasting Pass by Reference and Pass by Value
To understand pass by reference, it’s essential to contrast it with pass by value:
- Pass by value: When a function is called with a value as an argument, a new copy of that value is created and passed to the function. Modifying the value within the function would not affect the original value.
- Pass by reference: When a function is called with a reference to a variable as an argument, any modifications made to the referenced variable within the function would affect the original variable.
Python takes a unique approach. While all function arguments are passed by reference, the behavior might seem like a combination of pass by value and pass by reference due to the object’s mutability.
Using Pass by Reference Constructs
Now, let’s explore how pass by reference can be used in practice:
Avoiding Duplicate Objects
One advantage of pass by reference is avoiding the creation of duplicate objects when passing them to functions. Since objects are passed by reference, any modifications made to the object within the function would directly affect the original object.
In the example above, the modify_list
function modifies the numbers
list by appending the value 4
. The change made within the function affects the original numbers
list.
Returning Multiple Values
Pass by reference allows functions to return multiple values by modifying arguments. By passing mutable objects as arguments and modifying them within the function, multiple values can be assigned to those objects.
The calculate_sum_and_product
function calculates the sum and the product of two numbers. Instead of returning separate variables, it returns the sum and product by modifying the arguments a
and b
.
Creating Conditional Multiple-Return Functions
Pass by reference also allows the creation of conditional multiple-return functions. By modifying the arguments within the function, different values can be assigned to those arguments based on specific conditions.
In the find_min_and_max
function, the minimum and maximum values in a list of numbers are determined by modifying the min_value
and max_value
variables. The function returns these values as multiple results.
Passing Arguments in Python
To understand how pass by reference works in Python, let’s examine how assignment and function arguments behave.
Understanding Assignment in Python
In Python, variables are references to objects in memory. When assigning a variable to another, the reference to the original object is copied, not the object itself.
In the example above, the variable x
is assigned the value 10
. When the variable y
is assigned x
, the reference to the object representing 10
is copied to y
. Therefore, modifying x
does not affect the value of y
.
Exploring Function Arguments
When passing arguments to a function in Python, the references to the objects are passed. If the object is mutable, any modifications made to the object within the function would affect the original object.
In the example above, the modify_string
function attempts to modify the variable s
by concatenating ” World” to it. However, since strings are immutable, a new string is created. The original greeting
variable remains unchanged.
Replicating Pass by Reference With Python
Although Python passes all function arguments by reference, there are ways to replicate the pass by reference behavior more explicitly:
Best Practice: Return and Reassign
One approach is to return the modified object from the function and reassigned the variable to the returned object.
In this modified version of the modify_list
function, instead of modifying the list in place, it returns a new list with the modifications. The output is the same, but the modification is achieved by reassigning the variable numbers
to the returned list.
Best Practice: Use Object Attributes
Another approach is to use object attributes to achieve pass by reference behavior.
In this example, DataContainer
is a class with a data
attribute. By modifying the attribute within the modify_data
function, the change affects the original object.
Best Practice: Use Dictionaries and Lists
Using dictionaries and lists is a common way to achieve pass by reference behavior in Python. Mutable objects like dictionaries and lists can be modified in place, allowing changes to propagate to the original object.
In the modify_dict
function, the dictionary is modified by adding a new key-value pair. The modified dictionary is accessible outside the function.
Conclusion
Pass by reference is a unique aspect of Python’s function argument behavior. While all arguments are passed by reference, understanding how mutable objects behave and employing best practices can help achieve the desired results. By avoiding duplicate objects, returning multiple values, and using mutable object attributes, pass by reference-like behavior can be replicated in Python.