0Pricing
Python Academy · Урок

Практические шаблоны менеджеров контекста

Применяйте менеджеры контекста к файлам, блокировкам, таймерам и подключениям к DB.

«Практические шаблоны менеджеров контекста» — бесплатный урок Python Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Python Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Python Academy содержит 4 уроков всего.

Введение

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

Конвейер обработки файлов

Открывайте файлы ввода и вывода вместе, обрабатывайте их построчно и закрывайте оба автоматически.
import io
src = io.StringIO('line1\nline2\nline3')
dst = io.StringIO()
with src, dst:
    for line in src:
        dst.write(line.upper())
print(dst.getvalue())

Транзакция базы данных

Оберните операции с базой данных в CM: зафиксируйте изменения при успехе, выполните откат при исключении и всегда закрывайте ресурс.
from contextlib import contextmanager
@contextmanager
def db_transaction(conn):
    try:
        yield conn
        print('COMMIT')
    except Exception as e:
        print(f'ROLLBACK: {e}')
        raise
    finally:
        print('CLOSE')
with db_transaction({'execute': lambda q: print(f'SQL: {q}')}) as db:
    db['execute']('INSERT ...')

Блокировка потоков

with lock: захватывает блокировку, выполняет тело и освобождает блокировку при выходе — вручную вызывать захват и освобождение не требуется.
import threading
lock = threading.Lock()
shared = []
def add(x):
    with lock:
        shared.append(x)
add(1); add(2)
print(shared)

Смена каталога

os.chdir() глобально изменяет рабочий каталог. CM сохраняет и восстанавливает его.
from contextlib import contextmanager
import os
@contextmanager
def chdir(path):
    old = os.getcwd()
    os.chdir(path)
    try: yield
    finally: os.chdir(old)
original = os.getcwd()
with chdir('/tmp'):
    print('in tmp:', os.getcwd())
print('back:', os.getcwd())

Временные файлы

tempfile.NamedTemporaryFile в качестве CM автоматически создаёт и удаляет временный файл.
import tempfile
with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=True) as f:
    f.write('temp data')
    print('temp file:', f.name)
print('deleted')

Изменение переменной окружения

Временно установите переменную env для теста или подпроцесса, а затем восстановите её.
from contextlib import contextmanager
import os
@contextmanager
def env(**kwargs):
    old = {k: os.environ.get(k) for k in kwargs}
    os.environ.update({k:str(v) for k,v in kwargs.items()})
    try: yield
    finally:
        for k,v in old.items():
            if v is None: os.environ.pop(k,None)
            else: os.environ[k]=v
with env(DEBUG='1', LOG_LEVEL='DEBUG'):
    print(os.environ['DEBUG'])

Блок профилирования

Оберните блок в cProfile, чтобы измерить его производительность внутри CM.
from contextlib import contextmanager
import cProfile
@contextmanager
def profile():
    pr = cProfile.Profile()
    pr.enable()
    yield pr
    pr.disable()
with profile() as pr:
    sum(range(1000000))
print('profiled')

Сетевой сокет

Сокеты реализуют протокол CM: with socket.socket() as s: закрывает сокет при выходе.
import socket
try:
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.settimeout(0.1)
        print('socket ready')
except Exception as e:
    print(f'socket: {e}')

Перехват предупреждений

warnings.catch_warnings() перехватывает предупреждения, созданные внутри блока, что полезно в тестах.
import warnings
with warnings.catch_warnings(record=True) as w:
    warnings.simplefilter('always')
    warnings.warn('test warning')
print(len(w), w[0].category.__name__)

Комбинирование шаблонов

В реальных приложениях CM часто объединяют несколько шаблонов: транзакцию, logging и измерение времени в одном повторно используемом компоненте.
from contextlib import contextmanager
import time
@contextmanager
def timed_operation(name):
    print(f'[{name}] start')
    t0 = time.perf_counter()
    try:
        yield
        print(f'[{name}] done in {time.perf_counter()-t0:.4f}s')
    except Exception as e:
        print(f'[{name}] failed: {e}')
        raise
with timed_operation('loop'):
    sum(range(100000))

Быстрая проверка

Какая примитива для работы с потоками реализует протокол менеджера контекста для безопасного параллельного доступа?

Итоги

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

Продолжайте

Отличная работа! Следующий урок уже ждёт Вас.

Часто задаваемые вопросы

Урок «Практические шаблоны менеджеров контекста» бесплатный?

Да — полный текст урока «Практические шаблоны менеджеров контекста» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Python Academy, подпишись на CoddyKit PRO. Курс Python Academy содержит 4 уроков всего.

Чему я научусь в уроке «Практические шаблоны менеджеров контекста»?

Применяйте менеджеры контекста к файлам, блокировкам, таймерам и подключениям к DB. Ты практикуешь Python Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Python Academy?

Предыдущий опыт не требуется. Python Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Практические шаблоны менеджеров контекста»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Python Academy?

Да. Каждый урок Python Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Оператор with подробно
  2. Протокол __enter__ и __exit__
  3. contextlib: @contextmanager
  4. Практические шаблоны менеджеров контекста
← Назад к Python Academy