Introduction π
A Context Manager allows you to manage resources efficiently and safely using the with statement. It ensures proper setup and cleanup β even if errors occur.
Note
π‘ Guarantees cleanup β prevents resource leaks
π‘ Implemented using
__enter__ and __exit__1. Why Use Context Managers? π€
Without context manager:
without_with.py
f = open("data.txt", "r")
content = f.read()
f.close() # must remember to closeWith context manager:
with_statement.py
with open("data.txt", "r") as f:
content = f.read()β Automatically closes the file
β Cleaner & safer
2. How the with Statement Works π§
The with statement calls two special methods of the context manager:
- πΉ __enter__() β executed before the block starts
- πΉ __exit__() β executed after the block ends (even on error)
3. Creating Your Own Context Manager (Class-Based) ποΈ
custom_cm_class.py
class MyContext:
def __enter__(self):
print("Entering context...")
return "Resource"
def __exit__(self, exc_type, exc_val, exc_tb):
print("Exiting context...")
print("Error:", exc_type)
return False # return True to suppress errors
with MyContext() as r:
print("Using:", r)β You now understand how context managers actually work!
4. Using contextlib β Function-Based Context Manager π§©
Instead of creating a class, Python allows a simpler way using decorators.
contextlib_example.py
from contextlib import contextmanager
@contextmanager
def my_cm():
print("Enter")
yield "Resource"
print("Exit")
with my_cm() as r:
print("Using:", r)β Cleaner and easier to write
5. Real-World Example β File Handling π
file_handling.py
with open("data.txt", "w") as file:
file.write("Hello World")β File is automatically closed
6. Real-World Example β Database Connection ποΈ
db_connection.py
class DB:
def connect(self): print("Connected")
def close(self): print("Closed")
class DBManager:
def __enter__(self):
self.db = DB()
self.db.connect()
return self.db
def __exit__(self, *args):
self.db.close()
with DBManager() as db:
print("Working with DB...")7. Real-World Example β Timing Code Execution β±οΈ
timer_cm.py
import time
from contextlib import contextmanager
@contextmanager
def timer():
start = time.time()
yield
end = time.time()
print("Elapsed:", end - start)
with timer():
for _ in range(1_000_000):
pass8. Real-World Example β Suppressing Exceptions π
suppress_exception.py
from contextlib import suppress
with suppress(ZeroDivisionError):
print(10 / 0) # error is ignoredβ Only suppresses specified errors
9. Real-World Example β Redirect stdout π€
redirect_stdout.py
from contextlib import redirect_stdout
with open("log.txt", "w") as f:
with redirect_stdout(f):
print("This goes to the file")10. Real-World Example β Closing Multiple Resources β¨
exit_stack.py
from contextlib import ExitStack
with ExitStack() as stack:
f1 = stack.enter_context(open("a.txt"))
f2 = stack.enter_context(open("b.txt"))
print("Both files opened safely")β Manages multiple context managers elegantly
11. How Exceptions Work in Context Managers β οΈ
exception_handling.py
class CM:
def __enter__(self):
print("Enter")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("Exit")
if exc_type:
print("Error occurred:", exc_type)
return False # re-raise errorβ Returning True suppresses the exception
β Returning False re-raises it
Context Manager Cheat Sheet π
| Method / Tool | Purpose |
|---|---|
| __enter__() | Setup before block begins |
| __exit__() | Cleanup after block ends |
| with | Automatically handles setup/cleanup |
| @contextmanager | Create simple context managers |
| suppress | Ignore specific exceptions |
| redirect_stdout | Redirect output |
| ExitStack | Manage multiple resources |
Best Practices π‘
- β Always use context managers for files, DB connections, network calls
- β Use custom context managers to manage reusable resources
- β Use @contextmanager for simpler contexts
- β Use ExitStack for dynamic or multiple resources
- β Avoid suppressing errors unless absolutely needed
Conclusion π
You now fully understand Context Managers in Python! Want the next topic? Try Decorators, Generators, Exception Handling, or File Handling. Just tell me! π