In Python, functions are treated as “First-Class Objects.” This means that functions can be treated just like other data types such as numbers or strings: they can be assigned to variables, passed as arguments to other functions, or stored in lists and dictionaries.
Understanding this property allows you to design flexible and highly reusable code. This article explains the basic methods of treating functions as variables and their applications.
1. Assigning a Function to a Variable
After defining a function, the function name (without parentheses) refers to the function object itself. By assigning this to another variable, you can call the function through that variable.
Specific Code Example
Here is an example where we define a function that converts a string to uppercase and decorates it, and then assign it to another variable to use it.
def format_title(text):
"""Function to uppercase and decorate text"""
return f"*** {text.upper()} ***"
# Assign the function itself to the variable 'processor'
# Note: Write 'format_title', not 'format_title()'
processor = format_title
# Execute the function via the variable
result = processor("python programming")
print(result)
# Check which function the variable 'processor' refers to
print(f"Reference: {processor}")
Output:
*** PYTHON PROGRAMMING ***
Reference: <function format_title at 0x...>
You can see that the variable processor behaves exactly like the format_title function.
Important Distinction: With or Without Parentheses
format_title: The function object itself. Can be assigned to a variable.format_title("..."): The result of executing the function (return value).
When assigning, be careful not to add parentheses.
2. Passing Functions as Arguments (Higher-Order Functions)
Since functions can be treated as variables, you can pass “the processing logic itself” as an argument to another function. Functions that accept or return other functions are called “Higher-Order Functions.” This allows for designs where part of the processing is injected from the outside (Dependency Injection).
Specific Code Example
Let’s create a function that accepts a list of numbers and a “conversion function,” and returns a list with all elements converted.
def process_list(data_list, converter_func):
"""
Apply the passed function (converter_func) to each element of the list
"""
result_list = []
for item in data_list:
# Execute the function passed as an argument
converted_item = converter_func(item)
result_list.append(converted_item)
return result_list
# Function to use 1: Double the value
def double_value(x):
return x * 2
# Function to use 2: Convert to string format
def to_string_format(x):
return f"Value: {x}"
numbers = [10, 20, 30]
# 1. Pass the function that doubles the value
doubled = process_list(numbers, double_value)
print(f"Doubled: {doubled}")
# 2. Pass the function that converts to string
formatted = process_list(numbers, to_string_format)
print(f"Formatted: {formatted}")
Output:
Doubled: [20, 40, 60]
Formatted: ['Value: 10', 'Value: 20', 'Value: 30']
We were able to switch the processing logic simply by changing the function passed to process_list, without changing the contents of process_list itself.
3. Storing Functions in Lists or Dictionaries
Since functions are objects, they can also be handled as elements of lists or dictionaries. Using a dictionary is particularly common for implementing a “dispatch table,” which switches processing based on input, serving as an alternative to conditional branching (if-elif-else).
Specific Code Example
Here is a program that switches the function to execute based on the calculation type (string).
def add(x, y):
return x + y
def subtract(x, y):
return x - y
def multiply(x, y):
return x * y
# Register functions in a dictionary (Command Name: Function Object)
operations = {
"plus": add,
"minus": subtract,
"multi": multiply
}
def execute_calculation(command, a, b):
# Get the function from the dictionary
# Returns None if the command does not exist
func = operations.get(command)
if func:
return func(a, b)
else:
return "Invalid command"
# Execution
print(f"Addition: {execute_calculation('plus', 10, 5)}")
print(f"Multiplication: {execute_calculation('multi', 10, 5)}")
print(f"Error: {execute_calculation('divide', 10, 5)}")
Output:
Addition: 15
Multiplication: 50
Error: Invalid command
Using this method, when adding a new feature, you do not need to add more if statements inside the execute_calculation function; you simply need to add the function to the operations dictionary.
Summary
- Python functions are first-class objects and can be assigned to variables.
- By writing the function name without parentheses, you can handle it as an object without executing it.
- Passing functions as arguments to other functions or storing them in dictionaries allows you to create flexible and highly extensible programs.
