Using Python Context Managers to Write More Pythonic Code
This article explains the concept of Python context managers, demonstrates how the with statement simplifies resource handling compared to manual open/close patterns, and shows how defining __enter__ and __exit__ methods enables cleaner code, testing, and error handling.
In the Python community, writing "Pythonic" code means leveraging language features effectively, and context managers are a key tool for achieving this style.
Raymond Hettinger’s 2015 PyCon talk "Beyond PEP 8" highlighted the importance of context managers, and this article builds on that insight.
A context manager is an object that defines the runtime context for a with statement, handling entry and exit automatically.
Typical usage when opening a file:
with open('filename.txt', 'r') as datafile:
for line in datafile:
print(line)Without a context manager, the same task requires explicit close calls:
datafile = open('filename.txt', 'r')
for line in datafile:
print(line)
datafile.close()By using a context manager, the file is closed automatically at the end of the block, improving readability and safety.
Any class can become a context manager by implementing __enter__ and __exit__ methods; __enter__ runs when the block starts, and __exit__ runs when it finishes.
Hettinger’s example wraps network code in a context manager:
from nettools import NetworkElement
with NetworkElement('171.0.2.45') as ne:
for route in ne.routing_table:
print('%15s -> %s' % (route.name, route.ipaddr))The NetworkElement class defines only the essential methods:
class NetworkElement(object):
def __enter__(self):
return self
def __exit__(self, exctype, excinst, exctb):
if exctype == NetworkElementError:
logging.exception('No routing table found')
self.oldne.cleanup('rollback')
else:
self.oldne.cleanup('commit')
self.oldne.disconnect()Context managers are also handy for testing, such as asserting exceptions with pytest:
import pytest
def test_zero_division():
with pytest.raises(ZeroDivisionError):
1 / 0And for mocking with unittest.mock:
from unittest.mock import patch
with patch('Class.method', mocked_method):
# run test codeOverall, context managers enable concise resource management, validation, cleanup, and error handling, allowing developers to focus on core logic.
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
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.