Статья для понимания менеджера контекста Python

1. Что такое контекстный менеджер

Мы часто видим следующий код при обработке файлов, который является менеджером контекста:

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

Его смысл в том, чтобы открыть файл test.txt в текущем каталоге и распечатать его содержимое, что совпадает со следующим кодом:

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

Сравнивая два метода записи, можно обнаружить, что при использовании этого шага withавтоматического выполнения f.close()(закрытия файла) можно написать немного меньше кода.

Ниже объясняется, как реализовать такой менеджер контекста.



2. Как реализовать контекстный менеджер

1. Реализовано по классам

Если мы хотим реализовать openописанную выше функцию диспетчера контекста, мы можем создать класс и добавить методы __enter__и __exit__методы, как показано в следующем коде:

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())

выходной результат


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

Видно, что после того, как мы распечатали содержимое файла, автоматически выполняется операция закрытия файла.


Каково значение суммы __enter__и каково значение последнего ?__exit____exit__exc_type, exc_val, exc_tb


1)_ введите _

__enter__Условно говоря, это легче понять.Когда появится оператор with, он будет запущен.Когда есть возвращаемое значение, возвращаемое значение будет присвоено объявленной asпеременной, что мы и сделали выше as f.f


2)_ выход _

__exit__Он автоматически выполняется после завершения выполнения with.Значение параметров, стоящих за ним, следующее:

  1. exc_type: тип исключения
  2. exc_val: причина исключения
  3. exc_tb: информация о трассировке стека

Когда код, выполненный в with, сообщает об ошибке, в дополнение к тому, что код, содержащийся в with, не продолжает выполняться, сообщение об ошибке также будет помещено в три вышеуказанных параметра, например следующий код:

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())

выходной результат


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

нужно знать, это:

  1. Мы можем вручную указать __exit__возвращаемое значение True, чтобы оно не сообщало об ошибке.
  2. Когда информации об исключении нет, значения трех указанных выше параметров будут равны None.

2. Реализовано через contextlib

В Python есть встроенный contextlibмодуль для реализации менеджеров контекста.Он реализуется через генераторы.Этот yieldмодуль избавляет нас от необходимости создавать классы и __enter__ и __exit__.


Код contextlib, реализующий функцию открытия, выглядит следующим образом:

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())




Добро пожаловать, чтобы подписаться на новую рубрику «Создание автоматизированной тестовой платформы с нуля» !
Адрес онлайн-демонстрации платформы: http://121.43.43.59/ (Учетная запись: admin Пароль: 123456)


рекомендация

отblog.csdn.net/momoda118/article/details/121988918
рекомендация