An article to understand the Python context manager

1. What is a context manager

We often see the following code when processing files, which is the context manager:

with open('test.txt', encoding='utf-8') as f:
    print(f.readlines())

Its meaning is to open the test.txt file in the current directory and print its contents, which is the same as the following code:

f = open('test.txt', encoding='utf-8')
print(f.readlines())
f.close()

Comparing the two writing methods, it can be found that using this step of withautomatically executing f.close()(closing the file) can write a little less code.

How to implement such a context manager is explained below for you.



2. How to implement a context manager

1. Implemented by class

If we want to implement openthe above context manager function, we can create a class and add __enter__and __exit__methods, as shown in the following code:

class DiyOpen(object):

    def __init__(self, filename, **kwargs):
        self.f = open(filename, **kwargs)

    def __enter__(self):
        return self.f

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('关闭文件')
        self.f.close()


with DiyOpen('test.txt', encoding='utf-8') as f:
    print(f.readlines())

output result


['第一行\n', '第二行\n', '第三行']
关闭文件

It can be seen that after we print out the contents of the file, the operation of closing the file is automatically performed.


What is the meaning of the __enter__sum , and what is the meaning of the latter ?__exit____exit__exc_type, exc_val, exc_tb


1)_enter_

__enter__Relatively speaking, it is easier to understand. When the with statement appears, it will be triggered. When there is a return value, the return value will be assigned to the declared asvariable, which is what we have above as f.f


2)_exit_

__exit__It is automatically executed after the with execution is completed. The meaning of the parameters behind him is as follows:

  1. exc_type: exception type
  2. exc_val: exception reason
  3. exc_tb: stack trace information

When the code executed in with reports an error, in addition to not continuing to execute the code contained in with, the error message will also be put into the above three parameters, such as the following code:

class DiyOpen(object):

    def __init__(self, filename, **kwargs):
        self.f = open(filename, **kwargs)

    def __enter__(self):
        return self.f

    def __exit__(self, exc_type, exc_val, exc_tb):
        print(exc_type)
        print(exc_val)
        print(exc_tb)
        self.f.close()


with DiyOpen('test.txt', encoding='utf-8') as f:
    print(f.no())

output result


<class 'AttributeError'>
'_io.TextIOWrapper' object has no attribute 'no'
<traceback object at 0x000002A34B834900>

have to be aware of is:

  1. We can manually specify __exit__the return value of True to make it not report an error.
  2. When there is no exception information, the above three parameter values ​​will be None

2. Implemented through contextlib

Python has a built-in contextlibmodule for implementing context managers. It is implemented through generators yield. This module saves us from having to create classes and __enter__ and __exit__.


The contextlibcode that implements the open function is as follows:

from contextlib import contextmanager

@contextmanager
def diy_open(filename, **kwargs):
    f = open(filename, **kwargs)  # __init__
    try:
        yield f  # __enter__
    finally:  # __exit__
        f.close()

with diy_open('test.txt', encoding='utf-8') as f:
    print(f.readlines())




Welcome to subscribe to the new column "Building an Automated Test Platform from 0" !
Platform online demonstration address: http://121.43.43.59/ (Account: admin Password: 123456)


Guess you like

Origin blog.csdn.net/momoda118/article/details/121988918