Understanding Python Context Managers: __enter__ and __exit__ Methods with Practical Examples
This article explains Python's context manager protocol, detailing the roles of __enter__() and __exit__() methods, their typical use cases, and provides ten concrete code examples ranging from file handling and database connections to custom managers for networking, temporary files, and exception handling.
In Python, a context manager is an object that implements the special methods __enter__() and __exit__() , enabling the with statement to manage resource acquisition and release automatically.
__enter__() method: Called when entering a with block, it acquires resources or performs initialization and returns an object bound to the variable after the as keyword. Typical scenarios include opening files, establishing database connections, or setting up any resource that needs later cleanup.
with open('example.txt', 'r') as file:
content = file.read()
print(content) import sqlite3
with sqlite3.connect('example.db') as conn:
cursor = conn.cursor()
cursor.execute('SELECT * FROM users')
rows = cursor.fetchall()
print(rows) class MyContext:
def __enter__(self):
print('Entering the context')
self.resource = 'Initialized resource'
return self
def __exit__(self, exc_type, exc_value, traceback):
print('Exiting the context')
with MyContext() as context:
print(context.resource) import requests
with requests.get('https://api.example.com/data') as response:
data = response.json()
print(data) import tempfile
with tempfile.TemporaryFile(mode='w+') as temp_file:
temp_file.write('Temporary data')
temp_file.seek(0)
print(temp_file.read())__exit__() method: Executed when leaving the with block, regardless of whether an exception occurred, it releases resources or performs cleanup. It can also handle exceptions by inspecting the arguments.
class MyContext:
def __enter__(self):
print('Entering the context')
return self
def __exit__(self, exc_type, exc_value, traceback):
if exc_type is not None:
print('An error occurred:', exc_value)
return True # suppress the exception
print('Exiting the context')
try:
with MyContext():
print('Inside the context')
raise ValueError('Custom error')
except ValueError as e:
print('Caught custom error:', e)Additional examples demonstrate using with to close files, release database connections, and implement custom resource‑release managers.
with open('example.txt', 'w') as file:
file.write('Data to write') import sqlite3
conn = sqlite3.connect('example.db')
with conn:
cursor = conn.cursor()
cursor.execute('INSERT INTO users VALUES (1, "Alice")')
# transaction is committed automatically class MyFileOpener:
def __init__(self, filename):
self.filename = filename
def __enter__(self):
self.file = open(self.filename, 'r')
return self.file
def __exit__(self, exc_type, exc_value, traceback):
self.file.close()
with MyFileOpener('example.txt') as file:
content = file.read()
print(content) import tempfile
with tempfile.NamedTemporaryFile() as temp_file:
temp_file.write(b'Temporary data')
temp_file.seek(0)
print(temp_file.read())In summary, combining the with statement with properly defined __enter__() and __exit__() methods simplifies and secures resource management, ensuring that acquisition, usage, and cleanup are handled consistently even in the presence of errors.
Test Development Learning Exchange
Test Development Learning Exchange
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.