Managing Resources in Python with Context Managers (with statement)
Python Shorts — Part 5

In this post we will have a look at context managers in Python. These are used via the with … statement, and work well e.g. for managing resources. In these use-cases, we want to acquire and make use of an resource, and eventually free it when finished — ideally without much code from the user. One prominent example is opening files — i.e. we want to open a file, read / write to it, and then close it again.
Introductory Example: File Access via Context Managers
The preferred Python way of doing this is as follows:
with open('file.txt', 'w') as file:
file.write('test')I have to admit, when starting with Python, I actually did not pay much attention to the inconspicuous expression with — coming from different languages, casually brushing it off as mere namespacing or similar.
However, above example actually uses a context manager. Whenever we use with, we do so. In this case, open returns a file object, which then in turn provides a context manager.
Defining Custom Context Managers
Now, let us dive deeper, understand what a context manager actually is and does, and how to generate our own.
In summary, a context manager is a class that implements the following functions: __init__, __enter__, and __exit__.
__init__ is the constructor, __enter__ is called when we “enter” the code block managed by the context manager, __exit__ upon leaving.
For demonstration purposes, we create a naive context manager, purely to showcase its functionality:
class MyContextManager(object):
def __init__(self):
print("Init")
def __enter__(self):
print("Enter")
def __exit__(self, type, value, traceback):
print("Exit")
with MyContextManager():
print("Inside")Running this code prints the following output:
Init
Enter
Inside
Exit
Timed File Accessor
We finish this post with a somewhat more practical example, namely a context manager for accessing files — which automatically times how much time is spent with that file open:
import time
class TimedFile(object):
def __init__(self, file_name, mode):
self.file = open(file_name, mode)
self.start_time = None
def __enter__(self):
self.start_time = time.time()
return self.file
def __exit__(self, type, value, traceback):
self.file.close()
print(f"Time spent accessing file: {time.time() - self.start_time}s.")
with TimedFile('demo.txt', 'w') as file:
file.write("test")Hope you liked this post, happy to have you back next time!
This post is part of a series show-casing important Python concepts quickly. You can find the other parts here:
- Part 1: Lambda Functions in Python
- Part 2: Iterators in Python
- Part 3: Generators and Generator Expressions in Python
- Part 4: Advanced Iteration in Python with enumerate() and zip()
- Part 6: Generating Temporary Files and Directories in Python
- Part 7: Logging in Python
- Part 8: Partial Functions in Python
- Part 9: f-Strings in Python
More content at PlainEnglish.io.
Sign up for our free weekly newsletter. Follow us on Twitter, LinkedIn, YouTube, and Discord.
Interested in scaling your software startup? Check out Circuit.






