A function wrapper is a function that wraps another function and adds extra functionality before or after its execution. Wrappers are the foundation of Python decorators and help extend function behavior without modifying the original function.
def wrapper(func):
def inner():
print("Starting function...")
func()
print("Function completed.")
return inner
def greet():
print("Hello, Emma!")
greet = wrapper(greet)
greet()
Output
Starting function... Hello, Emma! Function completed.
Explanation:
- wrapper(func) accepts another function as an argument.
- inner() adds extra behavior before and after calling func().
- wrapper(greet) returns the wrapped version of greet.
- Calling greet() now executes inner(), which also runs the original function.
Examples
Example 1: In this example, we use the @ syntax to apply a function wrapper to another function.
def wrapper(func):
def inner():
print("Function started")
func()
print("Function finished")
return inner
@wrapper
def display():
print("Processing data...")
display()
Output
Function started Processing data... Function finished
Explanation:
- @wrapper applies the wrapper function to display().
- inner() executes additional code before and after the original function.
- This approach is equivalent to display = wrapper(display).
Example 2: In this example, a wrapper is used to calculate and display the execution time of a function.
import time
def timer(func):
def inner(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print("Execution Time:", round(end - start, 6), "seconds")
return result
return inner
@timer
def calculate():
total = 0
for i in range(100000):
total += i
calculate()
Output
Execution Time: 0.006498 seconds
Explanation:
- timer() records the start and end time of the function.
- The difference between the two times gives the execution duration.
- *args and **kwargs allow the wrapper to work with functions having any number of arguments.
Example 3: In this example, a wrapper checks whether a user is authorized before allowing the function to execute.
def login_required(func):
def inner(user):
if user != "admin":
print("Access Denied")
return
func(user)
return inner
@login_required
def view_dashboard(user):
print("Welcome", user)
view_dashboard("guest")
view_dashboard("admin")
Output
Access Denied Welcome admin
Explanation:
- login_required() checks whether the user is "admin".
- If the condition is not satisfied, the original function is not executed.
- If the user is authorized, the wrapped function runs normally.
- This pattern is commonly used for authentication and permission checks.