Менеджер контекста with open()

Менеджер контекста with open() в Python: автоматическое закрытие файла, обработка ошибок, вложенные файлы.

Менеджер контекста (with) гарантирует, что файл будет закрыт даже при возникновении ошибки — без явного вызова close().

Синтаксис

with open("data.txt", "r", encoding="utf-8") as f:
    content = f.read()
# здесь f уже закрыт — автоматически

Переменная f существует только внутри блока with. Когда блок завершается (в том числе из-за исключения), Python вызывает метод __exit__ файлового объекта, который закрывает файл.

Сравнение: без with и с with

# Небезопасно: если возникнет ошибка до close(), файл не закроется
f = open("data.txt", "w", encoding="utf-8")
f.write("Важные данные")
# ... какая-то ошибка ...
f.close()   # может не выполниться
# Безопасно: with гарантирует закрытие
with open("data.txt", "w", encoding="utf-8") as f:
    f.write("Важные данные")
# файл закрыт здесь, что бы ни случилось

Чтение и обработка в одном блоке

with open("numbers.txt", "w", encoding="utf-8") as f:
    for i in range(1, 6):
        f.write(f"{i}\n")

total = 0
with open("numbers.txt", "r", encoding="utf-8") as f:
    for line in f:
        total += int(line.strip())

print("Сумма:", total)

Вывод:

Сумма: 15

Два файла одновременно

Python позволяет открыть несколько файлов в одном with через запятую:

with open("source.txt", "w", encoding="utf-8") as src:
    src.write("Копируй меня\n")

with open("source.txt", "r", encoding="utf-8") as src, \
     open("dest.txt", "w", encoding="utf-8") as dst:
    for line in src:
        dst.write(line.upper())

with open("dest.txt", "r", encoding="utf-8") as f:
    print(f.read())

Вывод:

КОПИРУЙ МЕНЯ

Оба файла закроются автоматически по выходу из блока — даже если один из них выбросит ошибку при записи.

Частая ошибка

with open("test.txt", "w", encoding="utf-8") as f:
    f.write("данные")

# Попытка прочитать f после блока with
print(f.read())   # ValueError: I/O operation on closed file

После выхода из блока with файл закрыт. Любое обращение к f вне блока вызовет ValueError.

Коротко

  • with open(...) as f: автоматически закрывает файл при выходе из блока.
  • Файл закрывается даже при исключении — это делает with надёжнее явного close().
  • Несколько файлов можно открыть в одном with через запятую.
  • Обращаться к файловому объекту после with нельзя — он уже закрыт.
Проверьте себя
1. Что гарантирует менеджер контекста with при работе с файлами?
AФайл откроется быстрее
BФайл будет закрыт автоматически при выходе из блока
CСодержимое файла не изменится
DФайл будет прочитан целиком
2. Что произойдёт, если обратиться к файловому объекту f после блока with?
Af вернёт пустую строку
Bf перечитает файл с начала
CВозникнет ValueError: I/O operation on closed file
DНичего, f ещё открыт
3. Как открыть два файла одновременно в одном блоке with?
AЭто невозможно, нужно два отдельных with
Bwith open(f1) as a, open(f2) as b:
Cwith [open(f1), open(f2)] as files:
Ddouble_with open(f1, f2):
Поддержать проект