PythonDefining FunctionsHigher-Order Patterns

Higher-Order Patterns

Functions are first-class citizens in Python. You can pass them around, return them, and compose them to build expressive APIs.


First-Class Functions

def shout(text):
    return text.upper()
 
def whisper(text):
    return text.lower()
 
def speak(style, message):
    return style(message)
 
print(speak(shout, "hello"))

Passing Callbacks

def apply_and_log(func, value):
    result = func(value)
    print(f"Result: {result}")
    return result
 
apply_and_log(lambda x: x ** 2, 5)

Lambdas provide inline anonymous functions but are limited to single expressions. Use def for multi-line logic.


Returning Functions

def power(exp):
    def raise_to(base):
        return base ** exp
    return raise_to
 
square = power(2)
print(square(7))

Decorators

Decorators wrap functions with additional behaviour.

def trace(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__}")
        return func(*args, **kwargs)
    return wrapper
 
@trace
def greet(name):
    return f"Hello, {name}!"
⚠️

Always preserve metadata on decorated functions using functools.wraps. Without it, docstrings and names are lost.

from functools import wraps
 
def trace(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

Partial Functions

functools.partial pre-fills parameters to create specialised callables.

from functools import partial
 
send_email = partial(print, "Sending email to")
send_email("team@pythonforall.com")

Function Composition

Combine simple functions for powerful pipelines.

def compose(f, g):
    def inner(x):
        return f(g(x))
    return inner
 
strip_and_lower = compose(str.lower, str.strip)
print(strip_and_lower("  HELLO  "))

Functional Utilities

  • map(func, iterable) applies func lazily.
  • filter(func, iterable) keeps items where func(item) is truthy.
  • functools.reduce(func, iterable, initial) folds values into a single result.
from functools import reduce
 
nums = [1, 2, 3, 4]
product = reduce(lambda a, b: a * b, nums, 1)

Higher-Order Practice

Pyground

Create a decorator that times a function and prints the duration before returning the result.

Output:

Higher-order patterns keep code DRY by extracting cross-cutting concerns such as logging, caching, and timing into reusable decorators.