Function Composition in Python (original) (raw)

Last Updated : 03 Mar, 2025

**Function composition is a powerful concept where two or more functions are combined in such a way that the output of one function becomes the input for the next. It allows for the creation of complex functionality from simple, reusable building blocks. This concept is widely used in functional programming, but Python’s flexibility makes it simple to use function composition even though it’s not a purely functional language.

In **mathematical terms, if you have two functions F(x) and G(x), their composition is represented as F(G(x)). The output of G(x) is passed into F(x). In Python this means calling one function within another. For Example:

Python `

function to add 2 to a number

def add(x): return x + 2

function to multiply a number by 2

def mul(x): return x * 2

function composition f(g(x))

res = mul(add(5)) print(res)

`

**Explanation: add() adds 2 to the input (5), resulting in 7 and **mul() then multiplies 7 by 2, giving the final result 14.

Benefits of function composition

A Better Approach to function composition

Rather than manually **composing functions like in the above example, you can create a utility function that handles the composition of any two functions. This makes the process more flexible and reusable. Example:

Python `

function to compose two functions (f ∘ g)(x) = f(g(x))

def compose(f, g): return lambda x: f(g(x))

function to add 2 to a number

def add(x): return x + 2

function to multiply a number by 2

def mul(x): return x * 2

composite function

composed = compose(mul, add) res = composed(5) print(res)

`

**Explanation: compose() takes two functions as arguments and returns a lambda function that applies g(x) first, then f(g(x)).

Composing Multiple Functions

The above method allows you to compose two functions, but what if you want to compose more than two? We can modify our utility function to handle multiple functions using Python’s reduce() function from the functools module. Example:

Python `

from functools import reduce

function to compose two functions

def composite_fun(*funcs): def compose(f, g): return lambda x: f(g(x)) return reduce(compose, funcs, lambda x: x)

functions to add 2, subtract 1, and multiply by 2

def add(x): return x + 2

def mul(x): return x * 2

def sub(x): return x - 1

compose the functions

composed_fn = composite_fun(mul, sub, add)

apply the composed function

res = composed_fn(5) print(res)

`

**Explanation: reduce() applies the compose function across multiple functions sequentially. The execution order is add(5) → sub(7) → mul(6), resulting in 12.

Handling multiple arguments in function composition

Function composition typically expects each function to take a single input. However, if your functions need to handle multiple arguments, you can adjust the composition function to handle tuples or other structures.
**Example 1:

Python `

function to multiply both x and y by 2

def process_input(x, y): return x * 2, y * 2

function to sum x and y

def sum_inputs(args): x, y = args return x + y

compose functions to handle multiple arguments

def composed_fun(x, y): return sum_inputs(process_input(x, y))

res = composed_fun(3, 4) print(res)

`

**Explanation: process_input doubles both **x and **y, returning (6, 8) and **sum_inputs adds 6 + 8, resulting in 14.

**Example 2: Composing with different return types

Python `

Function to compose two functions (f ∘ g)(x) = f(g(x))

def compose(f, g): def inner(x): return f(g(x)) return inner

def greet(name): return f"Hello, {name}!"

def uppercase(greeting): return greeting.upper()

composed_fun = compose(uppercase, greet)

Apply the composed function

res = composed_fun("shakshi") print(res)

`

**Explanation: greet(“shakshi”) returns “Hello, shakshi!” and **uppercase converts it to “HELLO, SHAKSHI!” .

Function composition with decorators

In Python, decorators provide a way to modify or enhance functions or methods. **Function composition is also a common technique used in decorators to combine multiple behaviors into a single function. Example:

Python `

decorators for logging and timing

def log_function(func): def wrapper(*args, **kwargs): print(f"Calling {func.name} with arguments {args} and keyword arguments {kwargs}") return func(*args, **kwargs) return wrapper

def time_function(func): import time def wrapper(*args, **kwargs): start = time.time() result = func(*args, **kwargs) end = time.time() print(f"Execution time: {end - start} seconds") return result return wrapper

composing decorators

@log_function @time_function def add(x, y): return x + y

calling the decorated function

res = add(3, 4) print(res)

`

Output

Calling wrapper with arguments (3, 4) and keyword arguments {} Execution time: 1.430511474609375e-06 seconds 7

**Explanation: log_function logs function calls and arguments and time_function measures execution time. The add function is wrapped with both decorators, demonstrating function composition in decorators.