Functions as First-Class Objects
In Python, a function is an object in memory with a type, an identity, and a value. You can manipulate it like any other value:Lambda Functions
A lambda is a small, anonymous function defined with a single expression. Noreturn keyword is needed — the expression is evaluated and returned automatically.
Real-World Lambda Example
Multi-line Lambda Expressions (Nested Conditionals)
You can wrap a single expression across multiple lines using parentheses:Variable-Length Arguments (*args and **kwargs)
Accept an arbitrary number of arguments using starred parameters:
*argscollects extra positional arguments into a tuple.**kwargscollects extra keyword arguments into a dictionary.
Closures
A closure is a nested function that retains access to variables from its enclosing function’s scope — even after the outer function has finished executing. Three conditions must hold:- There is a nested (inner) function.
- The inner function references a variable from the outer scope.
- The outer function returns the inner function.
make_multiplier() creates an independent closure with its own factor value — double and triple are completely separate functions.
Decorators
A decorator is a higher-order function that wraps another function to add behaviour before, after, or around the original call — without modifying its source code.Writing a Basic Decorator
@my_decorator syntax is shorthand for say_hello = my_decorator(say_hello).
Decorating Functions with Arguments
Use*args and **kwargs in the wrapper so the decorator works with any function signature:
Practical Decorator Example — Timing
For production decorators, wrap the inner function with
functools.wraps(func) to preserve the original function’s __name__, __doc__, and other metadata: