🔄 The Relationship (Context and Decorator)
✅ Both context managers and decorators are about wrapping behavior
- They both allow you to run code before and after a certain block or function.
- They're commonly used to manage side effects like logging, timing, exception handling, and resource management.
🧩 Conceptual Connection
Feature | Context Manager | Decorator |
---|---|---|
Wraps a block of code | Yes (with statement) |
No (wraps a function) |
Wraps a function | Not directly (but can simulate) | Yes (@decorator ) |
Uses @contextmanager ? |
Yes, for function-style | Not required (but can use it) |
Can use yield for flow? |
Yes | Only if using generator-based decorators |
⚡ Example Side-by-Side
🎩 A Context Manager That Times a Block
from contextlib import contextmanager
import time
@contextmanager
def timer():
start = time.time()
yield
end = time.time()
print(f"Elapsed: {end - start:.2f} seconds")
with timer():
time.sleep(1)
🪄 A Decorator That Times a Function
import time
def timeit(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"Elapsed: {end - start:.2f} seconds")
return result
return wrapper
@timeit
def slow_function():
time.sleep(1)
slow_function()
🔁 Combining Both: Context Manager Inside a Decorator
from contextlib import contextmanager
import time
@contextmanager
def timer():
start = time.time()
yield
end = time.time()
print(f"[Context] Took {end - start:.2f}s")
def use_timer(func):
def wrapper(*args, **kwargs):
with timer():
return func(*args, **kwargs)
return wrapper
@use_timer
def do_work():
time.sleep(1)
do_work()
🧠 Summary
Similarity | Description |
---|---|
Both are wrappers | Context managers wrap code blocks, decorators wrap functions |
Pre/post logic | Both allow setup/teardown logic |
Cleaner code | They reduce boilerplate and improve readability |
🎯 Think of it like this:
- Context manager → wraps a code block
- Decorator → wraps a function
Thanks for Stopping by! Happy Leet coding
Connect with me on