Learning Objectives: After this lesson, you'll master the
withstatement, build custom context managers using both classes and contextlib, understand the descriptor protocol, and apply these patterns to manage resources safely.
Context Manager Lifecycle
Before diving into code, let's visualize the complete lifecycle of a context manager:
The key guarantee: __exit__ is ALWAYS called, even if an exception occurs in the body. This is what makes context managers safe for resource management.
Context Managers: The with Statement
Context managers ensure proper resource acquisition and cleanup, even when exceptions occur.
Why Context Managers Matter
The Context Manager Protocol
Building Practical Context Managers
Exception Handling in Context Managers
contextlib: Simplified Context Managers
The contextlib module provides tools for creating context managers without writing classes.
@contextmanager Decorator
Useful contextlib Utilities
Building Reusable Context Managers
Descriptors: The Attribute Protocol
Descriptors control what happens when attributes are accessed, set, or deleted.
Understanding Descriptors
Data vs Non-Data Descriptors
Practical Descriptor: Validated Attribute
Descriptor: Lazy Property
How Python Uses Descriptors
Combining Context Managers and Descriptors
Practice Exercises
Exercise 1: Database Transaction Context Manager
Exercise 2: Type-Checked Descriptor with Conversion
Key Takeaways
| Concept | Description |
|---|---|
| Context Manager | Object with __enter__ and __exit__ for resource management |
| @contextmanager | Create context managers from generators |
| ExitStack | Manage dynamic number of context managers |
| Descriptor | Object with __get__, __set__, __delete__ |
| Data Descriptor | Has __set__ or __delete__ - takes precedence over instance dict |
| Non-Data Descriptor | Only __get__ - instance dict takes precedence |
When to Use What
| Pattern | Use Case |
|---|---|
| Context Manager | Resource cleanup, temporary state changes, transactions |
| @contextmanager | Simple context managers without complex state |
| Descriptor | Reusable attribute validation, lazy properties, managed attributes |
| property | One-off computed or validated attributes |
Next Steps
In the next lesson, we'll explore Type Hints and Static Typing—learn type annotations, generics, Protocol, and how to use mypy for catching errors before runtime.
Ready for type-safe Python? Type hints await!