How to Share Variables Between Functions in Python: Best Practices
This guide explains how to share variables between different functions in Python. We'll explore various techniques, including:
- Returning values from functions.
- Passing variables as arguments.
- Using class attributes (for related functions).
- Using global variables (with a strong caution).
- Using function attributes.
We'll emphasize the most Pythonic and maintainable approaches.
Returning Values from Functions (Recommended)
The most common and recommended way to share data between functions is to have one function return a value, and the other function receive that value:
def func_a():
odd_numbers = [1, 3, 5, 7, 9]
return odd_numbers # Return the list
def func_b():
a_list = func_a() # Call func_a and store the result
print(a_list)
func_b() # Output: [1, 3, 5, 7, 9]
func_a
calculates or retrieves the data (odd_numbers
) and returns it.func_b
callsfunc_a
and stores the returned value in a local variable (a_list
).- This is the cleanest way to share data. It avoids global variables and makes the data flow explicit.
You can also pass arguments to functions:
def func_a(num):
odd_numbers = [1, 3, 5, 7, 9, num]
return odd_numbers
def func_b():
a_list = func_a(11)
print(a_list)
func_b() # Output: [1, 3, 5, 7, 9, 11]
Passing Variables as Arguments (Recommended)
Another excellent approach is to pass the variable as an argument to the function that needs it:
def func_a(num):
odd_numbers = [1, 3, 5, 7, 9, num]
return odd_numbers
def func_b(a_list): # func_b now accepts a list as an argument
print(a_list)
func_b(func_a(15)) # Pass the result of func_a directly to func_b
# Output: [1, 3, 5, 7, 9, 15]
func_b
is modified to accepta_list
as a parameter.- We call
func_a(15)
and immediately pass its return value as an argument tofunc_b
. - This is highly recommended because it makes the dependencies between your functions clear and explicit. It's easy to see where
func_b
gets its data.
Using Class Attributes (for Related Functions)
If your functions are logically related and operate on shared data, consider grouping them within a class:
class Employee():
def __init__(self, first, last):
self.first = first
self.last = last
self.salary = 100 # Instance variable, use this one
def increase_salary(self):
self.salary += 100
print(self.salary)
def decrease_salary(self):
self.salary -= 100
print(self.salary)
emp1 = Employee('tom', 'nolan')
emp1.increase_salary() # Output: 200
emp1.increase_salary() # Output: 300
emp1.decrease_salary() # Output: 200
self.salary
is an instance variable. EachEmployee
object will have its ownsalary
.- The methods (
increase_salary
,decrease_salary
) can access and modifyself.salary
directly. - This approach is suitable when your functions logically belong together as part of a class.
Using Global Variables (Generally Avoided)
While technically possible, using global
variables to share data between functions is generally discouraged:
full_name = '' # Global variable
def function_a():
global full_name # Declare intent to modify the global variable
full_name = 'tom nolan'
def function_b():
print(full_name) # Accesses the global variable
function_a()
function_b() # Output: tom nolan
global full_name
: Insidefunction_a
, this line must be present to indicate that you intend to modify the globalfull_name
, not create a local variable with the same name.- The
function_b
can then access the value assigned to the variable.
Why avoid globals?
- Hidden Dependencies: It's not immediately obvious from looking at
function_b
that it depends onfull_name
. - Difficult Debugging: If
full_name
is modified in unexpected ways, it can be hard to track down where the change occurred. - Reduced Reusability: Functions that rely on global variables are less self-contained and harder to reuse in other parts of your code.
- Testing Challenges: Testing functions that modify globals is more difficult, as you need to manage the global state.
Use globals only when absolutely necessary, and document them clearly. Constants (values that don't change) are sometimes acceptable as globals.
Using Function Attributes
You can also add and access the function attributes. However, this approach is not commonly used.
def function_a():
function_a.website = 'tutorialreference.com'
print(function_a.website)
def function_b():
print(function_a.website)
function_a() # Output: tutorialreference.com
function_b() # Output: tutorialreference.com
function_a.website
accesses the value that was previously set to the function.