Документация Python неофициальный перевод

contextlib.md

101 строк · 7.1 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.0/library/contextlib.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# `contextlib` – Утилиты для контекстов оператора [`with`](https://python-all.ru/3.0/reference/compound_stmts.html#with).89Этот модуль предоставляет утилиты для типичных задач, связанных с оператором [`with`](https://python-all.ru/3.0/reference/compound_stmts.html#with). Дополнительную информацию см. также в разделах [*Типы менеджеров контекста*](https://python-all.ru/3.0/library/stdtypes.html#typecontextmanager) и [*Менеджеры контекста оператора with*](https://python-all.ru/3.0/reference/datamodel.html#context-managers).1011Предоставляемые функции:1213#### `[contextlib.contextmanager]contextlib.contextmanager(func)`1415Эта функция – [*декоратор*](https://python-all.ru/3.0/glossary.html#term-decorator), который можно использовать для определения фабричной функции для менеджеров контекста оператора [`with`](https://python-all.ru/3.0/reference/compound_stmts.html#with), без необходимости создавать класс или отдельные методы [`__enter__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__enter__) и [`__exit__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__exit__).1617Простой пример (это не рекомендуется как реальный способ генерации HTML!):1819```python20from contextlib import contextmanager2122@contextmanager23def tag(name):24    print("<%s>" % name)25    yield26    print("</%s>" % name)2728>>> with tag("h1"):29...    print("foo")30...31<h1>32foo33</h1>34```3536Декорируемая функция при вызове должна возвращать [*генератор*](https://python-all.ru/3.0/glossary.html#term-generator)-итератор. Этот итератор должен передать (yield) ровно одно значение, которое будет связано с целями в предложении [`as`](https://python-all.ru/3.0/reference/compound_stmts.html#as) оператора [`with`](https://python-all.ru/3.0/reference/compound_stmts.html#with), если оно есть.3738В точке, где генератор выполняет yield, выполняется блок, вложенный в оператор [`with`](https://python-all.ru/3.0/reference/compound_stmts.html#with). Затем генератор возобновляется после выхода из блока. Если в блоке возникает необработанное исключение, оно повторно возбуждается внутри генератора в точке, где произошёл yield. Таким образом, можно использовать конструкцию [`try`](https://python-all.ru/3.0/reference/compound_stmts.html#try)...[`except`](https://python-all.ru/3.0/reference/compound_stmts.html#except)...[`finally`](https://python-all.ru/3.0/reference/compound_stmts.html#finally) для перехвата ошибки (если она есть) или для обеспечения выполнения очистки. Если исключение перехватывается лишь для того, чтобы залогировать его или выполнить какое-либо действие (а не подавить его полностью), генератор должен возобновить (reraise) это исключение. В противном случае менеджер контекста-генератор сообщит оператору [`with`](https://python-all.ru/3.0/reference/compound_stmts.html#with), что исключение обработано, и выполнение продолжится с оператора, непосредственно следующего за оператором [`with`](https://python-all.ru/3.0/reference/compound_stmts.html#with).3940#### `[contextlib.nested]contextlib.nested(mgr1[, mgr2[, ...]])`4142Объединяет несколько менеджеров контекста в один вложенный менеджер контекста.4344Пример такого кода:4546```python47from contextlib import nested4849with nested(A, B, C) as (X, Y, Z):50    do_something()51```5253эквивалентен следующему:5455```python56with A as X:57    with B as Y:58        with C as Z:59            do_something()60```6162Note that if the [`__exit__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__exit__) method of one of the nested context managers indicates an exception should be suppressed, no exception information will be passed to any remaining outer context managers. Similarly, if the [`__exit__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__exit__) method of one of the nested managers raises an exception, any previous exception state will be lost; the new exception will be passed to the [`__exit__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__exit__) methods of any remaining outer context managers. In general, [`__exit__()`](https://python-all.ru/3.0/reference/datamodel.html#object.__exit__) methods should avoid raising exceptions, and in particular they should not re-raise a passed-in exception.6364#### `[contextlib.closing]contextlib.closing(thing)`6566Возвращает контекстный менеджер, который закрывает *thing* после завершения блока. По сути эквивалентно следующему:6768```python69from contextlib import contextmanager7071@contextmanager72def closing(thing):73    try:74        yield thing75    finally:76        thing.close()77```7879И позволяет писать код следующим образом:8081```python82from contextlib import closing83from urllib.request import urlopen8485with closing(urlopen('http://www.python.org')) as page:86    for line in page:87        print(line)88```8990без необходимости явно закрывать `page`. Даже если произойдёт ошибка, `page.close()` будет вызван при выходе из блока [`with`](https://python-all.ru/3.0/reference/compound_stmts.html#with).9192> **См. также**93>94> **[**PEP 0343**](https://python-all.ru/3.0/library/contextlib.html) – оператор «with»**95>96> Спецификация, предыстория и примеры для оператора97>98> [`with`](https://python-all.ru/3.0/reference/compound_stmts.html#with)99>100> в Python.101