Decorators and Closures

Decorators

Decorators are functions that modify the behavior of other functions. They are used to add extra functionalities like authentication, logging, validation, etc.

Syntax:

def decorator(func):
    def wrapper():
        print("Before executing the function")
        func()
        print("After executing the function")
    return wrapper

@decorator
def greet():
    print("Hello!")

greet()

The @decorator is syntactic sugar for greet = decorator(greet)

Closures

A closure is an inner function that remembers and has access to the variables of the outer function, even after the outer function has finished executing.

Example:

def make_multiplier(factor):
    def multiply(number):
        return number * factor
    return multiply

times_two = make_multiplier(2)
print(times_two(5))  # Output: 10

Useful for creating custom functions dynamically.