
Chapter Outline
Chapter 10: Functional Features in Python
Python is a multi-paradigm language: it supports object-oriented, imperative, and functional programming styles. Functional features in Python make it easier to write concise, expressive, and reusable code.
In this chapter, we will explore:
- First-class functions
- Anonymous functions (lambdas) and higher-order tools:
map,filter, andreduce - Closures and decorators
- A project: Decorator-based Logger
10.1 First-Class Functions
In Python, functions are first-class citizens:
- They can be assigned to variables.
- They can be passed as arguments.
- They can be returned from other functions.
pythondef greet(name: str) -> str:return f"Hello, {name}!"# Assign a function to a variablesay_hello = greetprint(say_hello("Alice")) # Hello, Alice!# Pass a function as an argumentdef run_function(fn, value):return fn(value)print(run_function(greet, "Bob")) # Hello, Bob!
Functions behave like any other object in Python.
10.2 Lambdas and Higher-Order Functions
Lambda Functions
Lambdas are anonymous functions—small one-liners often used with higher-order functions.
pythonsquare = lambda x: x * xprint(square(5)) # 25
map()
Applies a function to each element in an iterable.
pythonnumbers = [1, 2, 3, 4]squares = list(map(lambda x: x * x, numbers))print(squares) # [1, 4, 9, 16]
filter()
Filters elements based on a predicate (function returning True/False).
pythonevens = list(filter(lambda x: x % 2 == 0, numbers))print(evens) # [2, 4]
reduce()
Reduces an iterable to a single value by repeatedly applying a function.
Note: reduce is in functools.
pythonfrom functools import reducenumbers = [1, 2, 3, 4]total = reduce(lambda acc, x: acc + x, numbers, 0)print(total) # 10
10.3 Closures
A closure is a function that remembers the variables from the scope in which it was created, even if that scope is gone.
pythondef multiplier(factor):def multiply_by(x):return x * factorreturn multiply_bytimes3 = multiplier(3)print(times3(10)) # 30
Here, multiply_by retains access to factor even after multiplier has returned.
10.4 Decorators
A decorator is a function that takes another function and returns a new function with added behavior. Common use cases: logging, timing, caching, access control.
python1def simple_decorator(fn):2 def wrapper(*args, **kwargs):3 print("Before function call")4 result = fn(*args, **kwargs)5 print("After function call")6 return result7 return wrapper89@simple_decorator10def greet(name):11 return f"Hello, {name}!"1213print(greet("Alice"))
Output:
bashBefore function callAfter function callHello, Alice!
10.5 Example: Decorator-based Logger
Let’s build a logging decorator to automatically log function calls.
python1import logging2from functools import wraps34# Configure logging5logging.basicConfig(6 filename="app.log",7 level=logging.INFO,8 format="%(asctime)s - %(levelname)s - %(message)s"9)1011def log_function_call(fn):12 """Decorator that logs function calls and their arguments."""13 @wraps(fn) # preserves original function name/docs14 def wrapper(*args, **kwargs):15 logging.info("Called %s with args=%s kwargs=%s", fn.__name__, args, kwargs)16 result = fn(*args, **kwargs)17 logging.info("%s returned %s", fn.__name__, result)18 return result19 return wrapper2021# Example usage22@log_function_call23def add(a, b):24 return a + b2526@log_function_call27def greet(name):28 return f"Hello, {name}!"2930if __name__ == "__main__":31 print(add(2, 3)) # 532 print(greet("Alice")) # Hello, Alice!
- The
log_function_calldecorator wraps any function. - Each time the function is called, logs are written before and after execution.
- The
@wrapsdecorator ensures the wrapped function keeps its metadata (__name__, docstring).
Sample Log Output (app.log)
console2023-11-05 12:34:10,001 - INFO - Called add with args=(2, 3) kwargs={}2023-11-05 12:34:10,002 - INFO - add returned 52023-11-05 12:34:10,003 - INFO - Called greet with args=('Alice',) kwargs={}2023-11-05 12:34:10,004 - INFO - greet returned Hello, Alice!
Summary
- First-class functions: Functions can be treated like data.
- Lambdas: Small anonymous functions for concise expressions.
- map, filter, reduce: Functional programming tools.
- Closures: Inner functions that remember outer scope.
- Decorators: Add reusable behavior to functions.
- Project: A logging decorator that records function calls.
Next, we’ll move into Data Structures and Algorithms in Python, building efficient code with Python’s built-in collections.
Check your understanding
Test your knowledge of Advanced Object-Oriented Programming in Python