Контекстный менеджер с использованием декоратора @contextmanager

Опубликовано: 2 Декабря, 2021

Декораторы - очень мощный и полезный инструмент в Python, поскольку он позволяет программистам изменять поведение функции или класса. Декораторы позволяют нам обернуть другую функцию, чтобы расширить поведение обернутой функции, без ее постоянного изменения.

Синтаксис:

@decorator
Функция def (аргументы):
    заявления (я)

Пример:

# Python program to demonstrate
# decorators
def msg_decorator(func):
# Inner function
def msg_wrapper(msg):
print ( "A decorated line:" , func(msg))
return msg_wrapper
# Using the decorator
@msg_decorator
def print_name(name):
return name
print_name( "Pooventhiran" )
Выход:
Декорированная линия: Повентиран

В этом примере всякий раз, когда вызывается print_name (), сначала вызывается msg_decorator с print_name в качестве аргумента. Внутри msg_decorator возвращается msg_wrapper, который просто вызывает любую функцию, переданную в msg_decorator, с переданными ей аргументами. Хотя этот пример прост, они очень эффективны в реальных случаях использования, таких как проверка граничных / особых условий, предварительная обработка и т. Д.

Примечание. Дополнительные сведения см. В разделе «Декораторы в Python».

Менеджер контекста

Менеджеры контекста - это менеджеры ресурсов Python. В большинстве случаев мы используем файлы как ресурсы (простой ресурс). Мы часто не заботимся о закрытии файлов в конце выполнения. Это плохая практика кодирования, а также вызывает проблемы, когда открывается слишком много файлов или когда программа завершается с ошибкой, поскольку ресурс не освобождается должным образом. Диспетчеры контекста помогают решить эту проблему, автоматически управляя ресурсами. В Python используется ключевое слово with

Пример:

# Python program to demonstrate
# Context Manager
with open ( 'testfile.txt' ) as in_file:
print (''.join(in_file.readlines()))

В показанном выше примере используемый файл управляется самим ContextManager, поскольку он закрывает файл даже в случае сбоя программы. Эта функция диспетчера контекста также может быть встроена в наши программы. Пользователь должен убедиться, что в классе есть методы: __enter__() и __exit__() . Давайте посмотрим на шаблон с этими специальными методами.

# Python program creating a
# context manager
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' )
# Driver code
with ContextManager() as manager:
print ( 'with statement block' )

Выход:

вызывается метод инициализации
метод ввода называется
с блоком операторов
метод выхода вызван

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

Использование @contextmanager

Мы должны использовать contextlib.contextmanager чтобы украсить функцию генератора, которая возвращает ровно один раз . Все до yield считается разделом __enter__, а все после - разделом __exit__. Функция генератора должна давать ресурс.

Пример: давайте перепишем приведенный выше пример с этим декоратором.

# Python program for creating a
# context manager using @contextmanager
# decorator
from contextlib import contextmanager
@contextmanager
def ContextManager():
# Before yield as the enter method
print ( "Enter method called" )
yield
# After yield as the exit method
print ( "Exit method called" )
with ContextManager() as manager:
print ( 'with statement block' )

Выход:

Введите метод под названием
с блоком операторов
Метод выхода вызван

Внимание компьютерщик! Укрепите свои основы с помощью базового курса программирования Python и изучите основы.

Для начала подготовьтесь к собеседованию. Расширьте свои концепции структур данных с помощью курса Python DS. А чтобы начать свое путешествие по машинному обучению, присоединяйтесь к курсу Машинное обучение - базовый уровень.