Summary: in this tutorial, you’ll learn about the Python context managers and how to use them effectively
Introduction to Python context managers #
A context manager is an object that defines a runtime context executing within the with statement.
Let’s start with a simple example to understand the context manager concept.
Suppose that you have a file called data.txt that contains an integer 100.
The following program reads the data.txt file, converts its contents to a number, and shows the result to the standard output:
f = open('data.txt')
data = f.readlines()
# convert the number to integer and display it
print(int(data[0]))
f.close()Code language: Python (python)The code is simple and straightforward.
However, the data.txt may contain data that cannot be converted to a number. In this case, the code will result in an exception.
For example, if the data.txt contains the string '100' instead of the number 100, you’ll get the following error:
ValueError: invalid literal for int() with base 10: "'100'"Code language: Python (python)Because of this exception, Python may not close the file properly.
To fix this, you may use the try...except...finally statement:
try:
f = open('data.txt')
data = f.readlines()
# convert the number to integer and display it
print(int(data[0]))
except ValueError as error:
print(error)
finally:
f.close()Code language: Python (python)Since the code in the finally block always executes, the code will always close the file properly.
This solution works as expected. However, it’s quite verbose.
Therefore, Python provides you with a better way that allows you to automatically close the file after you complete processing it.
This is where context managers come into play.
The following shows how to use a context manager to process the data.txt file:
with open('data.txt') as f:
data = f.readlines()
print(int(data[0])
Code language: Python (python)In this example, we use the open() function with the with statement. After the with block, Python will close automatically.
Python with statement #
Here is the typical syntax of the with statement:
with context as ctx:
# use the the object
# context is cleaned upCode language: Python (python)How it works.
- When Python encounters the
withstatement, it creates a new context. The context can optionally return anobject. - After the
withblock, Python cleans up the context automatically. - The scope of the
ctxhas the same scope as thewithstatement. It means that you can access thectxboth inside and after thewithstatement.
The following shows how to access the f variable after the with statement:
with open('data.txt') as f:
data = f.readlines()
print(int(data[0]))
print(f.closed) # TrueCode language: Python (python)Python context manager protocol #
Python context managers work based on the context manager protocol.
The context manager protocol has the following methods:
__enter__()– setup the context and optionally return some object__exit__()– cleanup the object.
If you want a class to support the context manager protocol, you need to implement these two methods.
Suppose that ContextManager is a class that supports the context manager protocol.
The following shows how to use the ContextManager class:
with ContextManager() as ctx:
# do something
# done with the contextCode language: Python (python)When you use ContextManager class with the with statement, Python implicitly creates an instance of the ContextManager class (instance) and automatically call __enter__() method on that instance.
The __enter__() method may optionally return an object. If so, Python assigns the returned object the ctx.
Notice that ctx references the object returned by the __enter__() method. It doesn’t reference the instance of the ContextManager class.
If an exception occurs inside the with block or after the with block, Python calls the __exit__() method on the instance object.