What are Context Managers?

Context managers manage resources automatically using the with statement. They ensure proper setup and cleanup, even if errors occur.

Using 'with' Statement

Most common use is with files:

# Without context manager
file = open('data.txt', 'r')
content = file.read()
file.close()  # Easy to forget!

# With context manager
with open('data.txt', 'r') as file:
    content = file.read()
# File automatically closed

Creating Context Manager

Use class with __enter__ and __exit__:

class MyContext:
    def __enter__(self):
        print("Entering")
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Exiting")
        return False

with MyContext():
    print("Inside")

Using contextlib

Simpler syntax with decorator:

from contextlib import contextmanager

@contextmanager
def my_context():
    print("Entering")
    yield
    print("Exiting")

with my_context():
    print("Inside")

Common Use Cases

  • File handling: Automatic file closing
  • Database connections: Automatic connection closing
  • Locks: Thread synchronization
  • Timing: Measure execution time
  • Resource management: Any resource that needs cleanup

Best Practices

  • Always use 'with': For file operations
  • Use contextlib: For simpler context managers
  • Handle exceptions: In __exit__ method
  • Return False: From __exit__ to propagate exceptions

Next Steps

Learn about decorators and generators.