Context Manager in Python
Last Updated : 03 Nov, 2022
Managing Resources: In any programming language, the usage of resources like file operations or database connections is very common. But these resources are limited in supply. Therefore, the main problem lies in making sure to release these resources after usage. If they are not released then it will lead to resource leakage and may cause the system to either slow down or crash. It would be very helpful if users have a mechanism for the automatic setup and teardown of resources. In Python, it can be achieved by the usage of context managers which facilitate the proper handling of resources. The most common way of performing file operations is by using the keyword as shown below:
Python3
with open ("test.txt") as f: data = f.read() |
Let’s take the example of file management. When a file is opened, a file descriptor is consumed which is a limited resource. Only a certain number of files can be opened by a process at a time. The following program demonstrates it.
Python3
file_descriptors = [] for x in range ( 100000 ): file_descriptors.append( open ( 'test.txt' , 'w' )) |
Output:
Traceback (most recent call last): File "context.py", line 3, in OSError: [Errno 24] Too many open files: 'test.txt'
An error message saying that too many files are open. The above example is a case of file descriptor leakage. It happens because there are too many open files and they are not closed. There might be chances where a programmer may forget to close an opened file.
Managing Resources using context manager: Suppose a block of code raises an exception or if it has a complex algorithm with multiple return paths, it becomes cumbersome to close a file in all the places. Generally in other languages when working with files try-except-finally is used to ensure that the file resource is closed after usage even if there is an exception. Python provides an easy way to manage resources: Context Managers. The with keyword is used. When it gets evaluated it should result in an object that performs context management. Context managers can be written using classes or functions(with decorators).
Creating a Context Manager: When creating context managers using classes, user need to ensure that the class has the methods: __enter__() and __exit__(). The __enter__() returns the resource that needs to be managed and the __exit__() does not return anything but performs the cleanup operations. First, let us create a simple class called ContextManager to understand the basic structure of creating context managers using classes, as shown below:
Python3
class ContextManager(): def __init__( self ): print ( 'init method called' ) def __enter__( self ): print ( 'enter method called' ) return self def __exit__( self , exc_type, exc_value, exc_traceback): print ( 'exit method called' ) with ContextManager() as manager: print ( 'with statement block' ) |
Output:
init method called enter method called with statement block exit method called
In this case, a ContextManager object is created. This is assigned to the variable after the keyword i.e manager. On running the above program, the following get executed in sequence:
- __init__()
- __enter__()
- statement body (code inside the with block)
- __exit__()[the parameters in this method are used to manage exceptions]
File management using context manager: Let’s apply the above concept to create a class that helps in file resource management. The FileManager class helps in opening a file, writing/reading contents, and then closing it.
Python3
class FileManager(): def __init__( self , filename, mode): self .filename = filename self .mode = mode self . file = None def __enter__( self ): self . file = open ( self .filename, self .mode) return self . file def __exit__( self , exc_type, exc_value, exc_traceback): self . file .close() with FileManager( 'test.txt' , 'w' ) as f: f.write( 'Test' ) print (f.closed) |
Output:
True
File management using context manager and with statement: On executing the with block, the following operations happen in sequence:
- A FileManager object is created with test.txt as the filename and w(write) as the mode when __init__ method is executed.
- The __enter__ method opens the test.txt file in write mode(setup operation) and returns a file object to variable f.
- The text ‘Test’ is written into the file.
- The __exit__ method takes care of closing the file on exiting the with block(teardown operation). When print(f.closed) is run, the output is True as the FileManager has already taken care of closing the file which otherwise needed to be explicitly done.
Database connection management using context manager: Let’s create a simple database connection management system. The number of database connections that can be opened at a time is also limited(just like file descriptors). Therefore context managers are helpful in managing connections to the database as there could be chances that the programmer may forget to close the connection.
Python3
from pymongo import MongoClient class MongoDBConnectionManager(): def __init__( self , hostname, port): self .hostname = hostname self .port = port self .connection = None def __enter__( self ): self .connection = MongoClient( self .hostname, self .port) return self .connection def __exit__( self , exc_type, exc_value, exc_traceback): self .connection.close() with MongoDBConnectionManager( 'localhost' , '27017' ) as mongo: collection = mongo.connection.SampleDb.test data = collection.find({ '_id' : 1 }) print (data.get( 'name' )) |
Database connection management using context manager and with statement: On executing the with block, the following operations happen in sequence:
- A MongoDBConnectionManager object is created with localhost as the hostname name and 27017 as the port when the __init__ method is executed.
- The __enter__ method opens the MongoDB connection and returns the MongoClient object to variable mongo.
- The test collection in the SampleDb database is accessed and the document with _id=1 is retrieved. The name field of the document is printed.
- The __exit__ method takes care of closing the connection on exiting the with block(teardown operation).
Similar Reads
Python Naming Conventions
Python, known for its simplicity and readability, places a strong emphasis on writing clean and maintainable code. One of the key aspects contributing to this readability is adhering to Python Naming Conventions. In this article, we'll delve into the specifics of Python Naming Conventions, covering
4 min read
Python Exit handlers (atexit)
atexit is a module in python which contains two functions register() and unregister(). The main role of this module is to perform clean up upon interpreter termination. Functions that are registered are automatically executed upon interpreter termination. Whenever a program is killed by a signal not
2 min read
__exit__ in Python
Context manager is used for managing resources used by the program. After completion of usage, we have to release memory and terminate connections between files. If they are not released then it will lead to resource leakage and may cause the system to either slow down or crash. Even if we do not re
3 min read
Concrete Exceptions in Python
In Python, exceptions are a way of handling errors that occur during the execution of the program. When an error occurs Python raises an exception that can be caught and handled by the programmer to prevent the program from crashing. In this article, we will see about concrete exceptions in Python i
3 min read
Python Main Function
Main function is like the entry point of a program. However, Python interpreter runs the code right from the first line. The execution of the code starts from the starting line and goes line by line. It does not matter where the main function is present or it is present or not. Since there is no mai
5 min read
Context Variables in Python
Context variable objects in Python is an interesting type of variable which returns the value of variable according to the context. It may have multiple values according to context in single thread or execution. The ContextVar class present in contextvars module, which is used to declare and work wi
4 min read
Importlib package in Python
In this article, we are going to know about the Importlib package in the Python programming language. The importlib package is primarily utilized by Python applications for dynamic imports during runtime. In layman's terms, it allows the user to load modules as he/she discovers them. This package ha
6 min read
Inner Class in Python
Python is an Object-Oriented Programming Language, everything in Python is related to objects, methods, and properties. A class is a user-defined blueprint or a prototype, which we can use to create the objects of a class. The class is defined by using the class keyword. Example of class [GFGTABS] P
5 min read
Coroutine in Python
Prerequisite: GeneratorsWe all are familiar with function which is also known as a subroutine, procedure, sub-process, etc. A function is a sequence of instructions packed as a unit to perform a certain task. When the logic of a complex function is divided into several self-contained steps that are
5 min read
Matplotlib.pyplot.rc_context() in Python
Matplotlib is a library in Python and it is numerical - mathematical extension for NumPy library. Pyplot is a state-based interface to a Matplotlib module which provides a MATLAB-like interface. There are various plots which can be used in Pyplot are Line Plot, Contour, Histogram, Scatter, 3D Plot,
2 min read