with statement and context manager

Posted by jokeruk on Tue, 18 Jan 2022 18:04:44 +0100

1. Use of with statement

Example code for writing data to a file:

 # 1. Open file as write
 f = open("1.txt", "w")
 # 2. Write file contents
 f.write("hello world")
 # 3. Close file
 f.close()

Code Description:

  • The file must be closed after use, because the file object will occupy the resources of the operating system, and the operating system can open a limited number of files at the same time

There may be some potential safety hazards in this way, and the error code is as follows:

 # 1. Open file read
 f = open("1.txt", "r")
 # 2. Read file contents
 f.write("hello world")
 # 3. Close file
 f.close()

Operation results:

Code Description:

  • Since IOError may occur during file reading and writing, once an error occurs, the subsequent f.close() will not be called.
  • In order to ensure that the file can be closed correctly whether there is an error or not, we can use try Finally

Safe writing, the code is as follows:

try:
    # 1. Open file read
    f = open("1.txt", "r")
    # 2. Read file contents
    f.write("xxxxx")

except IOError as e:
    print("file operation error", e)

finally:
    # 3. Close file
    f.close()

Operation results:

Although the code of this method runs well, the disadvantage is that the code is too lengthy and needs to add a try except finally statement, which is not very convenient and easy to forget

In this case, Python provides the writing method of the with statement, which is simple and safe. After the execution of the with statement, the file closing operation will be called automatically. Even if there are exceptions, the file closing operation will be called automatically.

Example code of with statement:

# 1. Open file as write
with open("1.txt", "w") as f:
    # 2. Read file contents
    f.write("hello world")

2. Context manager

A class as long as it implements__ enter__ () and__ exit__ () the two methods and the objects created through this class are called context managers.

The context manager can use the with statement. The reason why the with statement is so powerful is supported by the context manager. That is to say, the file object just created with the open function is a context manager object.

Custom context manager class to simulate file operation:

Define a File class to implement__ enter__ () and__ exit__ () method, and then use the with statement to complete the operation File. Example code:

class File(object):

    # Initialization method
    def __init__(self, file_name, file_model):
        # Define variable save file name and open mode
        self.file_name = file_name
        self.file_model = file_model

    # Above method
    def __enter__(self):
        print("Go to the above method")
        # Return file resource
        self.file = open(self.file_name,self.file_model)
        return self.file

    # Following methods
    def __exit__(self, exc_type, exc_val, exc_tb):  # The internal parameters are fixed and will be generated automatically
        print("Go to the method below")
        self.file.close()


if __name__ == '__main__':

    # Using with to manage files
    with File("1.txt", "r") as file:
        file_data = file.read()
        print(file_data)

Operation results:

Code Description:

  • __ enter__ Represents the above method, which needs to return an operation file object
  • __ exit__ Represents the following method. The with statement will be executed automatically after execution, and the method will be executed even if an exception occurs.

3. Another implementation of context manager

If you want a function to become a context manager, Python also provides a decorator of @ contextmanager, which further simplifies the implementation of the context manager. The function is divided into two parts by yield. The statement above yield__ enter__ Method, and the following statements in yield__ exit__ Method, and the parameter immediately following yield is the return value of the function.

# Import decorator
from contextlib import contextmanager


# Decorator decorates the function to be called a context manager object
@contextmanager
def my_open(path, mode):
    try:
        # Open file
        file = open(path, mode)
        # The code before yield is like the above method
        yield file
    except Exception as e:
        print(e)
    finally:
        print("over")
        # yield the following code is like the following method
        file.close()


# Using the with statement
with my_open('1.txt', 'w') as f:
    f.write("hello , the simplest context manager")

4. Summary

  • Python provides a with statement to simplify the operation of resource release. The operation using the with statement is established in the context manager (implementing _enter and _exit) Based on
  • Python also provides a @ contextmanager decorator to further simplify the implementation of upper and lower managers, so that a function can become a context manager and be used in combination with the with statement

Topics: Python