← Назад к вопросам

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

2.0 Middle🔥 111 комментариев
#REST API и HTTP

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Оператор with для контекстных менеджеров

Основной синтаксис

Для работы с контекстными менеджерами в Python используется оператор with. Это один из самых важных инструментов для безопасного управления ресурсами в Python.

with expression as variable:
    # код, который использует переменную
    pass

Зачем нужны контекстные менеджеры?

Контекстные менеджеры гарантируют, что ресурсы (файлы, соединения с БД, блокировки) будут правильно освобождены, даже если в коде возникнет исключение. Это следует принципу RAII (Resource Acquisition Is Initialization).

Практические примеры

Работа с файлами:

# Плохо - файл может остаться открытым
f = open("file.txt")
data = f.read()
f.close()

# Хорошо - файл гарантированно закроется
with open("file.txt") as f:
    data = f.read()

Работа с блокировками:

import threading

lock = threading.Lock()

# Безопасное использование блокировки
with lock:
    # критическая секция
    shared_resource.value += 1
# lock автоматически освобождается

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

Можно создавать свои контекстные менеджеры двумя способами:

1. Через класс с методами __enter__ и __exit__:

class DatabaseConnection:
    def __init__(self, host):
        self.host = host
        self.connection = None
    
    def __enter__(self):
        print(f"Подключение к {self.host}")
        self.connection = f"connection to {self.host}"
        return self.connection
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(f"Закрытие соединения с {self.host}")
        self.connection = None
        return False  # не подавляем исключения

# Использование
with DatabaseConnection("localhost") as conn:
    print(f"Работаем с: {conn}")

2. Через декоратор @contextmanager:

from contextlib import contextmanager

@contextmanager
def database_connection(host):
    print(f"Подключение к {host}")
    connection = f"connection to {host}"
    try:
        yield connection
    finally:
        print(f"Закрытие соединения")

# Использование
with database_connection("localhost") as conn:
    print(f"Работаем с: {conn}")

Несколько контекстных менеджеров

# Python 3.1+
with open("input.txt") as f_in, open("output.txt", "w") as f_out:
    f_out.write(f_in.read())

# Эквивалентно вложенности:
with open("input.txt") as f_in:
    with open("output.txt", "w") as f_out:
        f_out.write(f_in.read())

Важные детали

  • Метод __exit__ вызывается всегда, даже если произошло исключение
  • Если __exit__ возвращает True, исключение подавляется
  • Если возвращает False или ничего не возвращает, исключение распространяется дальше
  • Контекстные менеджеры значительно упрощают код и делают его безопаснее

Оператор with - это одна из самых полезных фишек Python для надежного управления ресурсами.

Какой оператор используется для контекстных менеджеров? | PrepBro