Returning a function from a function - Python
In Python, functions are first-class objects, allowing them to be assigned to variables, passed as arguments and returned from other functions. This enables higher-order functions, closures and dynamic behavior.
Example:
def fun1(name):
def fun2():
return f"Hello, {name}!"
return fun2
# Get the function returned by fun1()
msg = fun1("shakshi")
# Call the returned function
print(msg())
Output
Hello, shakshi!
Explanation: fun1 defines fun2, which captures the name parameter. When called with "shakshi", fun1 returns fun2, assigned to msg. Calling msg() returns "Hello, shakshi!".
Properties of first-class functions
It's essential to understand what makes functions "first-class" in Python. A first-class object is an entity that can be:
- Assigned to a variable: Functions can be stored in variables, just like other data types (e.g., integers, strings).
- Passed as arguments: Functions can be passed as arguments to other functions.
- Returned from other functions: Functions can be returned from other functions.
- Stored in data structures: Functions can be stored in lists, dictionaries, or other data structures.
Because functions are first-class objects, they provide flexibility in designing highly reusable and dynamic programs
Examples
Example 1: Returning a Function Without Arguments
def B():
print("Inside the method B.")
def A():
print("Inside the method A.")
return B # function A returns function B
return_fun = A() # call A(), which returns function B
return_fun() # call function B through return_fun
Output
Inside the method A. Inside the method B.
Explanation: When A() is called, it returns B, which is assigned to return_fun. Calling return_fun() invokes B .
Example 2: Returning a function with arguments
def B(st2):
print("Good " + st2 + ".")
def A(st1, st2):
print(st1 + " and ", end="")
B(st2) # call B with st2
A("Hello", "Morning") # call A with two arguments
Output
Hello and Good Morning.
Explanation: A calls B with st2 as an argument. When A("Hello", "Morning") is called, it prints "Hello and " and then calls B("Morning")
Example 3: Returning a lambda function
def A(u, v):
w = u + v # Sum of u and v
z = u - v # Difference of u and v
return lambda: print(w * z) # return lambda to print product of w and z
return_fun = A(5, 2) # get lambda function
print(return_fun)
return_fun() # execute lambda
Output
<function A.<locals>.<lambda> at 0x7faef1653380> 21
Explanation: A calculates the sum (w) and difference (z) of u and v, then returns a lambda function that prints the product of w and z. When A(5, 2) is called, it returns the lambda, which is assigned to return_fun.
Use cases and benefits
Returning functions from functions is a versatile and powerful feature in Python. It can be used in various scenarios, such as:
- Callbacks: Functions can be returned to be called later in response to some event.
- Closures: Functions can capture variables from the enclosing scope, enabling encapsulation and maintaining state across function calls.
- Function Generators: Functions can be returned based on parameters, allowing dynamic creation of behavior at runtime.
- Decorators: Decorators are a form of higher-order functions that modify or enhance other functions by returning a new function.
Example: Creating a custom power function
def power(exponent):
return lambda base: base ** exponent # return lambda to raise base to exponent
square = power(2) # function to square a number
cube = power(3) # function to cube a number
print(square(5)) # square 5
print(cube(3)) # cube 3
Output
25 27
Explanation: power() returns a lambda function that raises a number (base) to a given exponent. Calling power(2) creates a function square to square a number and calling power(3) creates a function cube to cube a number.