Перейти к основному содержимому

Python: Создание объектов, поддерживающих выражение with

Все знают о том, как, например, открыть файл, или, возможно, как установить блокировку с использованием оператора with. Но можно ли самостоятельно реализовать механизм управления блокировками? Да, это вполне реально. Протокол управления контекстом исполнения реализуется с использованием методов __enter__ и __exit__:

class Connection:  
def __init__(self):
...

def __enter__(self):
# Инициализируем соединение...

def __exit__(self, type, value, traceback):
# Закрываем соединение...

with Connection() as c:
# __enter__() executes
...
# conn.__exit__() executes

Это — наиболее распространённый способ реализации возможностей менеджера контекста в Python, но то же самое можно сделать и проще:

from contextlib import contextmanager  

@contextmanager
def tag(name):
print(f"<{name}>")
yield
print(f"</{name}>")

with tag("h1"):
print("This is Title.")

Здесь протокол управления контекстом реализован с использованием декоратора contextmanager. Первая часть функции tag (до yield) выполняется при входе в блок with. Затем выполняется сам этот блок, а после этого выполняется оставшаяся часть функции tag.