Что такое контекстный менеджер в python
Перейти к содержимому

Что такое контекстный менеджер в python

  • автор:

Тип contextmanager, контекстный менеджер

Оператор with в Python поддерживает концепцию контекста среды выполнения, определенного контекстным менеджером. Типичные области применения контекстных менеджеров включают сохранение и восстановление различных типов глобального состояния, блокировку и разблокировку ресурсов, закрытие открытых файлов и т. д.

Содержание:

  • Оператор контекста with ;
    • Как работает менеджер контекста;
    • Метод __enter__() ;
    • Метод __exit__() ;

    Синтаксис оператора контекста with :

    with EXPRESSION as TARGET: SUITE 
    manager = (EXPRESSION) enter = type(manager).__enter__ exit = type(manager).__exit__ value = enter(manager) hit_except = False try: TARGET = value SUITE except: hit_except = True if not exit(manager, *sys.exc_info()): raise finally: if not hit_except: exit(manager, None, None, None) 

    Выражение EXPRESSION , непосредственно следующее за ключевым словом with является «выражением контекста», так как это выражение обеспечивает основной ключ к среде выполнения, которую менеджер контекста устанавливает для продолжительности тела выражения.

    Как работает менеджер контекста with :

    1. Выражение контекста (выражение, указанное в EXPRESSION ) оценивается для получения менеджера контекста.
    2. Менеджер контекста загружает метод __enter__() для последующего использования.
    3. Менеджер контекста загружает метод __exit__() для последующего использования.
    4. Менеджер контекста вызывает метод __enter__() .
    5. Если TARGET была включена в оператор with , то ей присваивается возвращаемое значение из метода __enter__() .
      Обратите внимание, что оператор with гарантирует, что если метод __enter__() возвращается без ошибки, то всегда будет вызываться метод __exit__() . Таким образом, если ошибка возникает во время присваивания значения через оператор as , то она будет обрабатываться так же, как и ошибка, возникающая внутри with .
    6. Последовательность команд выполнена.
    7. Вызван метод __exit__() . Если исключение вызвало выход из последовательности команд, то его тип exc_type , значение exc_val и информация о трассировке exc_tb передаются в качестве аргументов __exit__() . В противном случае предоставляется три аргумента None .

    Если последовательность команд была завершена из-за исключения, а возвращаемое значение из метода __exit__() было False , то исключение вызывается повторно. Если возвращаемое значение было True , то исключение подавляется и выполнение продолжается с оператора, следующего за оператором with .

    Если последовательность команд была завершена по любой причине, кроме исключения, то возвращаемое значение из __exit__() игнорируется, и выполнение продолжается.

    При наличии нескольких контекстных менеджеров, то они обрабатываются так, как если бы несколько операторов with были вложенными:

    with A() as a, B() as b: SUITE # Эквивалентно with A() as a: with B() as b: SUITE 

    С версии Python 3.10 поддерживается использование круглых скобок для написания нескольких диспетчеров. Это позволяет форматировать длинную коллекцию диспетчеров контекста в несколько строк аналогично тому, как это можно с операторами импорта. Например, теперь действительны все эти примеры:

    with (CtxManager() as example): . with ( CtxManager1(), CtxManager2() ): . with (CtxManager1() as example, CtxManager2()): . with (CtxManager1(), CtxManager2() as example): . with ( CtxManager1() as example1, CtxManager2() as example2 ): . 

    Допускается использовать конечную запятую в конце заключенной группы:

    with ( CtxManager1() as example1, CtxManager2() as example2, CtxManager3() as example3, ): . 

    Реализация/протокол менеджера контекста.

    Протокол контекстных менеджеров реализован с помощью пары методов, которые позволяют определяемым пользователем классам определять контекст среды выполнения, который вводится до выполнения тела инструкции и завершается при завершении инструкции:

    contextmanager.__enter__() :

    Метод contextmanager.__enter__() вводит контекст среды выполнения и возвращает либо себя, либо другой объект, связанный с контекстом среды выполнения. Значение, возвращаемое этим методом, привязывается к идентификатору в предложении as оператора with , использующего этот контекстный менеджер.

    Ярким примером контекстного менеджера, который возвращает себя, является объект file . Файловые объекты возвращают себя из __enter__() , чтобы разрешить использование встроенной функции open() в качестве контекстного выражения в операторе with .

    with open('/etc/passwd') as fp: for line in fp: print line.rstrip() 
    contextmanager.__exit__(exc_type, exc_val, exc_tb) :

    Метод contextmanager.__exit__() предоставляет выход из контекста среды выполнения и возвращает логический флаг, указывающий, следует ли подавлять любое возникшее исключение. При возникновении исключения во время выполнения тела оператора with , аргументы содержат тип исключения exc_type , значение exc_val и информацию о трассировке exc_tb . В противном случае все три аргумента — это None .

    Если у метода contextmanager.__exit__() установить возвращаемое значение в return True , то это приведет к тому, что оператор with будет подавлять возникающие исключения внутри себя и продолжит выполнение с оператора, непосредственно следующим за оператором with . В противном случае исключение exc_type продолжает распространяться после завершения выполнения этого метода. Исключения, возникающие во время выполнения этого метода, заменят все исключения, возникшие в теле оператора with .

    Передаваемое исключение exc_type никогда не следует повторно вызывать явно, вместо этого метод contextmanager.__exit__() должен возвращать return False , чтобы указать, что метод завершился успешно и не хочет подавлять возникшее исключение. Это позволяет коду управления контекстом легко определять, действительно ли метод contextmanager.__exit__() потерпел неудачу.

    Упрощенное создание менеджеров контекста.

    Поддержка упрощенного создания менеджеров контекста предоставляется модулем contextlib .

    Многие контекстные менеджеры, например, файлы и контексты на основе генераторов будут одноразовыми объектами. После вызова метода __exit__() менеджер контекста больше не будет находиться в работоспособном состоянии (например, файл был закрыт или базовый генератор завершил выполнение).

    Необходимость создания нового объекта менеджера контекста для каждого оператора with — это самый простой способ избежать проблем с многопоточным кодом и вложенными операторами, пытающимися использовать один и тот же контекстный менеджер. Не случайно, что все стандартные менеджеры контекста модуля contextlib , поддерживающие повторное использование, происходят из модуля threading и все они уже разработаны для решения проблем, создаваемых потоковым и вложенным использованием.

    Это означает, что для сохранения менеджера контекста с определенными аргументами инициализации, которые будут использоваться в нескольких операторах with , как правило, необходимо будет сохранить его в вызываемом объекте с нулевым аргументом, который затем вызывается в выражении контекста каждого оператора, а не кэшировать непосредственно менеджер контекста. Если это ограничение не применяется, это должно быть ясно указано в документации соответствующего контекстного менеджера.

    Примеры использования менеджеров контекста:

    Шаблон для обеспечения того, что блокировка, полученная в начале блока, освобождается, когда блок закончен:
    @contextmanager def locked(lock): lock.acquire() try: yield finally: lock.release() 
    with locked(myLock): # Здесь код выполняется с удержанным myLock. # lock.release() гарантированно будет выполнен, когда блок # будет завершен (даже по необработанному исключению). 
    Шаблон для открытия файла, который обеспечивает закрытие файла при завершении блока:
    @contextmanager def opened(filename, mode="r"): f = open(filename, mode) try: yield f finally: f.close() 
    with opened("/etc/passwd") as f: for line in f: print line.rstrip() 
    Шаблон для фиксации или отката транзакции базы данных:
    @contextmanager def transaction(db): db.begin() try: yield None except: db.rollback() raise else: db.commit() 
    Временно перенаправить стандартный вывод для однопоточных программ:
    @contextmanager def stdout_redirected(new_stdout): save_stdout = sys.stdout sys.stdout = new_stdout try: yield None finally: sys.stdout = save_stdout 
    with opened(filename, "w") as f: with stdout_redirected(f): print "Hello world" 
    Вариант с функцией open() , который также возвращает условие ошибки:
    @contextmanager def opened_w_error(filename, mode="r"): try: f = open(filename, mode) except IOError, err: yield None, err else: try: yield f, None finally: f.close() 
    with opened_w_error("/etc/passwd", "a") as (f, err): if err: print "IOError:", err else: f.write("guido::0:0::/:/bin/sh\n") 
    • КРАТКИЙ ОБЗОР МАТЕРИАЛА.
    • Утиная типизация ‘Duck Typing’
    • Что такое вызываемый объект callable?
    • Как проверить тип переменной/объекта
    • Логический тип данных bool
    • Целые числа int
    • Ограничение длины преобразования целочисленной строки
    • Вещественные числа float
    • Комплексные числа complex
    • Типы последовательностей
    • Список list
    • Кортеж tuple
    • Диапазон range
    • Текстовые строки str
    • Словарь dict
    • Множество set и frozenset
    • Итератор Iterator, протокол итератора
    • Генератор generator и выражение yield
    • Контекстный менеджер with
    • Байтовые строки bytes
    • Байтовый массив bytearray
    • Тип memoryview, буфер обмена
    • Файловый объект file object
    • Универсальный псевдоним GenericAlias
    • Объект объединения Union

    Контекстные менеджеры в Python

    В программах часто используются такие ресурсы, как файлы или базы данных. Но эти ресурсы ограничены в доступе. Поэтому основная проблема заключается в том, чтобы освободить их после использования. Если они не будут освобождены, это приведет к утечке ресурсов и может вызвать замедление работы системы или ее сбой. Было бы хорошо, если бы у пользователя был механизм для автоматического захвата и освобождения ресурсов. В Python это может быть достигнуто с помощью контекстных менеджеров, которые облегчают правильную обработку ресурсов.

    Для работы с файлами часто используется конструкция, показанная в примере ниже. Она позволяет захватить ресурс, выполнить необходимые операции, а затем освободить его:

    with open("test.txt") as f: data = f.read()

    Давайте возьмем пример управления файлами. Когда файл открывается, используется дескриптор файла, который является ограниченным ресурсом. Только определенное количество файлов может быть открыто процессом одновременно. Следующая программа демонстрирует это.

    file_descriptors = [] for x in range(100000): file_descriptors.append(open('test.txt', 'w'))
    Traceback (most recent call last): 
    File "context.py", line 3, in
    OSError: [Errno 24] Too many open files: 'test.txt'

    Мы получили сообщение об ошибке, указывающее, что открыто слишком много файлов. Приведенный выше пример представляет собой случай утечки файлового дескриптора. Это происходит потому, что слишком много открытых файлов и они не закрыты. Бывает, что программист просто забывает закрыть открытый файл.

    Управление ресурсами с помощью контекстного менеджера

    Предположим, что блок кода вызывает исключение или содержит сложный алгоритм с несколькими инструкциями return , и тогда становится неудобно закрывать файл во всех местах.

    Как правило, в других языках при работе с файлами для того, чтобы файловый ресурс был закрыт после использования, даже если было возбуждено исключение, используется конструкция try-except-finally. Python предоставляет простой способ управления ресурсами: контекстные менеджеры. Выражение, следующее после ключевого слова with , должно возвращать объект, реализующий протокол Context Manager. Контекстные менеджеры могут быть написаны с использованием классов или функций (с помощью декораторов).

    Создание контекстного менеджера

    При создании контекстных менеджеров с использованием классов пользователь должен убедиться, что у класса есть следующие методы: __enter__() и __exit__() . __enter__() возвращает требуемый ресурс, а __exit __() ничего не возвращает, но выполняет освобождение ресурсов.

    Для начала, давайте создадим простой класс ContextManager , чтобы понять базовую структуру создания контекстных менеджеров с использованием классов, как показано ниже:

    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')
    init method called
    enter method called
    with statement block
    exit method called

    В этом случае создается объект ContextManager . Он присваивается переменной, следующей за ключевым словом as ( manager в данном случае). При запуске вышеуказанной программы последовательно выполняются следующие действия:

    • __init__()
    • __enter__()
    • инструкции (код внутри блока with )
    • __exit__() [параметры этого метода используются для управления исключениями]

    Управление файлами с помощью контекстного менеджера

    Давайте используем вышеприведенную концепцию для создания класса, который применяется для управлении файловыми ресурсами. Класс FileManager помогает открыть файл, записать/прочитать содержимое, а затем закрыть его.

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

    Управление файлами с помощью контекстного менеджера и конструкции with

    При выполнении блока with последовательно выполняются следующие операции:

    • Создается объект FileManager с аргументами test.txt и w (write) при выполнении метода __init__ .
    • Метод __enter__ открывает файл test.txt в режиме записи (write) и возвращает объект FileManager , который присваивается переменной f .
    • Текст «Test» записывается в файл.
    • Метод __exit__ обеспечивает закрытие файла при выходе из блока with .

    Когда выполняется print(f.closed) , то на экран выводится True , поскольку FileManager уже позаботился о закрытии файла, что в противном случае нужно было бы сделать явно.

    Управление подключением к базе данных с помощью контекстного менеджера

    Давайте создадим простую систему управления подключениями к базе данных. Количество подключений к базе данных, которые могут быть открыты одновременно, также ограничено (как и файловые дескрипторы). Поэтому контекстные менеджеры полезны при управлении соединениями с базой данных, так как есть вероятность, что программист может забыть закрыть соединение.

    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 def __exit__(self, exc_type, exc_value, exc_traceback): self.connection.close() # подключение к localhost with MongoDBConnectionManager('localhost', '27017') as mongo: collection = mongo.connection.SampleDb.test data = collection.find() print(data.get('name'))

    Управление подключениями к базе данных с помощью контекстного менеджера и оператора with

    При выполнении блока with последовательно выполняются следующие операции:

    • Создается объект MongoDBConnectionManager с аргументами localhost и 27017 при выполнении метода __ init__ .
    • Метод __enter__ открывает соединение mongodb и возвращает объект MongoDBConnectionManager переменной mongo .
    • Осуществляется доступ к коллекции (collection) test в базе данных SampleDb и извлекается документ с _id=1 . На экран выводится поле name документа.
    • Метод __exit__ обеспечивает закрытие соединения при выходе из блока with .

    Как устроен with

    Контекстные менеджеры (оператор with ) встречаются там, где перед совершением действия нужно что-то настроить, а после – прибраться. Например, чтобы прочитать файл, мы используем такой контекстный менеджер:

    with open(filepath) as file_handler: return json.load(file_handler) 

    Здесь “настройкой” является открытие файла, а “уборкой” – его закрытие. Сейчас мы разберемся, как утроены контекстные менеджеры в Питоне.

    Свой контекстный менеджер

    Заменим нетипичную конструкцию with. as более распространенной try. finally :

    file_handler = open(filepath).__enter__() try: print(json.load(file_handler)) finally: file_handler.__exit__() 

    Мы видим, что файл открывается при вызове __enter__ , а закрывается при вызове __exit__ . При этом закрытие файла произойдет, даже если json.load бросит исключение.

    Напишем собственный контекстный менеджер, который создаст книгу в Excel, а по завершении работы с ней – сохранит. Другими словами, мы хотели бы использовать его вот так:

    import openpyxl with create_workbook('workbook_name.xlsx') as workbook: fill_worksheet(workbook.active, some_data) 

    Согласно документации, для этого нам достаточно написать класс, который определяет методы __enter__ и __exit__ . Вот так он будет выглядеть:

    class CreateWorkbook: def __init__(self, filepath): self.filepath = filepath def __enter__(self): self.workbook = Workbook() return self.workbook def __exit__(self, *args): self.workbook.save(self.filepath) 

    Соответственно, использовать его можно так:

    with CreateWorkbook('workbook_name.xlsx') as workbook: worksheet = workbook.active worksheet.cell(row=1, column=1, value="1") 

    И этот код действительно создает книгу и записывает число 1 в первую ячейку. Проблема только в том, что так контекстные менеджеры не пишут.

    Свой контекстный менеджер, ver. 2.0

    Первый недостаток нашего контекстного менеджера заключается в том, что он позволяет вызвать __exit__ перед __enter__ . Если это произойдет, поднимется непонятное исключение. Для того, чтобы избежать этого, воспользуемся генератором:

    from openpyxl import Workbook def create_workbook(filepath): workbook = Workbook() yield workbook workbook.save(filepath) class CreateWorkbook: def __init__(self, filepath): self.filepath = filepath def __enter__(self): self.generator = create_workbook(self.filepath) return next(self.generator) def __exit__(self, *args): next(self.generator, None) 

    В вызове next(self.generator, None) второй аргумент нужен для того, чтобы next не поднимал исключение StopIteration .

    Теперь заметим, что генератор create_workbook содержит всю предметно-ориентированную логику. Поэтому класс CreateWorkbook можно обобщить так, чтобы он от нее не зависил и работал с любыми генераторами. Заодно переименуем его в ContextManager :

    class ContextManager: def __init__(self, generator): self.generator = generator def __call__(self, *args, **kwargs): self.args, self.kwargs = args, kwargs return self def __enter__(self): self.generator_instance = self.generator(*self.args, **self.kwargs) return next(self.generator_instance) def __exit__(self, *args): next(self.generator_instance, None) 

    В конструкторе ContextManager мы принимаем генератор, при вызове объекта записываем переданные генератору параметры, а при вызове __enter__ вызываем генератор. Теперь класс ContextManager можно использовать следующим образом:

    from openpyxl import Workbook def create_workbook(filepath): workbook = Workbook() yield workbook workbook.save(filepath) with ContextManager(create_workbook)('workbook_name.xlsx') as workbook: worksheet = workbook.active worksheet.cell(row=1, column=1, value="1") 

    Вызов ContextManager(create_workbook)(‘workbook_name.xlsx’) выглядит некрасиво. Исправим это:

    create_workbook = ContextManager(create_workbook) with create_workbook('workbook_name.xlsx') as workbook: worksheet = workbook.active worksheet.cell(row=1, column=1, value="1") 

    Здесь заметим, что ContextManager(create_workbook) , по сути, возвращает тот же объект create_workbook , но с дополнительным поведением. Ровно для этой задачи в Питоне существует специальный синтаксический сахар – декораторы. Нам даже не потребуется изменять ContextManager :

    @ContextManager def create_workbook(filepath): workbook = Workbook() yield workbook workbook.save(filepath) with create_workbook('workbook_name.xlsx') as workbook: worksheet = workbook.active worksheet.cell(row=1, column=1, value="1") 

    Самое приятное, что наш универсальный ContextManager уже есть в стандартной библиотеке Питона, и называется он contextmanager . Весь наш пример можно переписать так:

    from contextlib import contextmanager from openpyxl import Workbook @contextmanager def create_workbook(filepath): workbook = Workbook() yield workbook workbook.save(filepath) with create_workbook('workbook_name.xlsx') as workbook: worksheet = workbook.active worksheet.cell(row=1, column=1, value="1") 

    И это еще не всё. Если после yield workbook пользовательский код поднимит исключение, мы не сохраним книгу. Чтобы этого избежать, обернем это выражение в try. finally :

    @contextmanager def create_workbook(filepath): workbook = Workbook() try: yield workbook finally: workbook.save(filepath) 

    А вот так контекстные менеджеры писать принято.

    Резюме

    • Контекстные менеджеры нужны там, где есть какая-то “настройка”, действия пользователя и следующая за ними “уборка”.
    • У контекстного менеджера обязательно есть атрибуты __enter__ и __exit__ .
    • Не обязательно писать целый класс для нового контекстного менеджера, достаточно обернуть генератор в декоратор contextmanager .
    • yield стоит оборачивать в блок try. finally .

    Дальнейшее чтение

    • Более подробное описание методов __enter__ и __exit__ .
    • Подброрка библиотечных контекстных менеджеров и рецептов к ним.
    • Часть доклада Рэймонда Хэттингера, одного из разработчиков Питона, про декораторы и контекстные менеджеры.

    Попробуйте бесплатные уроки по Python

    Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.

    Переходите на страницу учебных модулей «Девмана» и выбирайте тему.

    Python. Урок 21. Работа с контекстным менеджером

    Follow us on Google Plus Follow us on rss

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

    • Работа с контекстным менеджером
    • Создание своего контекстного менеджера
    • Работа с contextlib

    Работа с контекстным менеджером

    Рассмотрим пример, на котором будут показаны преимущества работы с контекстным менеджером. Задача состоит в следующем: записать в файл file.txt строку hello .

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

    f = open(‘file.txt’, ‘w’) f.write(‘hello’) f.close()

    Но это не очень хорошее решение, если в процессе работы с файлом (запись, чтение), произошло исключение, то функция close() не будет вызвана, что влечет за собой возможную потерю данных. Для решения этого вопроса воспользуемся обработкой исключения:

    f = open('file.txt', 'w') try: f.write('hello') except: print('Some error!') finally: f.close()

    Для того, чтобы не писать дополнительный код, связанный с обработкой исключений (это неудобно и об этом можно забыть), можно воспользоваться конструкцией with… as :

    with open('file.txt', 'w') as f: f.write('hello')

    Такая конструкция позволяет захватить ресурс (в данном случае файл), выполнить нужный набор операций (запись данных), а перед выходом – освободить ресурс.

    Создание своего контекстного менеджера

    Если сущность, которую вы создаете, по стилю работы с ней похожа на файл, т.е. предполагает захват ресурса и освобождение, либо требует выполнения определенных действий перед началом работы и при завершении, то хорошим решением будет создать свой контекстный менеджер, с которым можно будет работать с помощью конструкции with..as. Для этого, в класс необходимо добавить два метода: __enter__ и __exit__ .

    Перед тем как перейти к примеру, демонстрирующему работу с этими функциями, рассмотрим, что происходит (какие методы и в каком порядке вызываются) в конструкции:

    with open('file.txt', 'w') as file_data: file_data.write('hello')
    1. Оператор with сохраняет метод __exit__ класса File .
    2. Вызывается метод __enter__ класса File .
    3. __enter__ открывает файл и возвращает его.
    4. Дескриптор открытого класса передается в file_data .
    5. В файл записываются данные через метод write.
    6. Вызывается сохраненный метод __exit__ , который закрывает файл.

    Если внутри конструкции with происходит исключение, то оно передается в метод __exit__ , в котором производится его обработка и освобождение ресурсов (закрытие файла).

    Пример реализации контекстного менеджера

    Создадим класс, у объекта которого необходимо вызывать метод post_work() перед прекращением работы с ним:

    class Resource: def __init__(self, name): print('Resource: create <>'.format(name)) self.__name = name def get_name(self): return self.__name def post_work(self): print('Resource: close')

    Теперь создадим контекстный менеджер для работы с Resource , который можно будет использовать с оператором with:

    class ResourceForWith: def __init__(self, name): self.__resource = Resource(name) def __enter__(self): return self.__resource def __exit__(self, type, value, traceback): self.__resource.post_work()

    Пример работы с ResourceForWith и конструкцией with :

    with ResourceForWith('Worker') as r: print(r.get_name())

    Если выполнить этот код, то получим следующий вывод на консоль

    >python test.py Resource: create Worker Worker Resource: close

    Работа с contextlib

    В стандартную библиотеку Python входит модуль contextlib , который содержит утилиты для построения и работы с контекстными менеджерами.

    Рассмотрим только один инструмент из всего набора – contextmanager . contextmanager используется как декоратор для функции, превращая ее в контекстный менеджер. При этом схема конструирования такая: все, что написано до оператора yield вызывается в рамках функции __enter__ , а все что после – в рамках __exit__ .

    Рассмотрим несколько примеров:

    from contextlib import contextmanager @contextmanager def processor(): print('--> start processing') yield print('
    

    В contextmanager можно завернуть работу с файлом :

    from contextlib import contextmanager @contextmanager def open_file(path, mode): f = open(path, mode) yield f f.close() with open_file('test.txt', 'w') as fw: fw.write('hello')

    P.S.

    Вводные уроки по “Линейной алгебре на Python” вы можете найти соответствующей странице нашего сайта . Все уроки по этой теме собраны в книге “Линейная алгебра на Python”.

    Если вам интересна тема анализа данных, то мы рекомендуем ознакомиться с библиотекой Pandas. Для начала вы можете познакомиться с вводными уроками. Все уроки по библиотеке Pandas собраны в книге “Pandas. Работа с данными”.

    Раздел: Python Уроки по Python Метки: Python, Уроки Python

    Python. Урок 21. Работа с контекстным менеджером : 4 комментария

    1. Олег 02.04.2020 Добрый день! Подскажите, как можно реализовать менеджер контекста для измерения времени выполнения какого-либо кода с помощью with и показывать результат измерения после завершения исполнения этого кода.
      по типу: >>> with Timer ():
      do_some_long_stuff () Time: 10.004614966004738
    1. yossik 11.04.2020 Например вот так: from contextlib import contextmanager
      import time @contextmanager
      def timer():
      start_time = time.time()
      yield
      print(“— %s seconds —” % (time.time() – start_time)) with timer():
      for i in range(1000):
      junk = list(range(i**2))
      print(“–DONE–“)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *