summaryrefslogtreecommitdiff
path: root/PYTHON/WITH.md
blob: 437e03d74a89512d19df94096e1c647388efd89d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Ещё одна мощная и идиоматичная конструкция в Python — это менеджеры контекста и оператор ==with==. Они кардинально упрощают работу с ресурсами, которые требуют обязательной "очистки" после использования, например, файлы, сетевые соединения или блокировки потоков.

Представьте, что вы открываете файл для записи. Крайне важно его потом закрыть, иначе данные могут не сохраниться, а файловый дескриптор останется занят. Классический, но многословный способ гарантировать закрытие — использовать `try...finally:
```sh
f = open('my_file.txt', 'w')
try:
    f.write('Важные данные!')
    # ... тут может произойти ошибка
finally:
    f.close() # Закроется в любом случае
```

Работает, но выглядит громоздко. Python предлагает элегантную альтернативу с with:
```sh
with open('my_file.txt', 'w') as f:
    f.write('Важные данные!')
    # ... тут тоже может произойти ошибка
# Как только блок `with` завершается (нормально или из-за ошибки),
# Python АВТОМАТИЧЕСКИ вызывает f.close()!
```

**В чём магия with?**

Объекты, используемые с with (как тот, что возвращает open()), реализуют так называемый "протокол менеджера контекста". У них есть специальные методы (__enter__ и __exit__). Оператор with вызывает __enter__ при входе в блок и гарантированно вызывает __exit__ при выходе из блока, передавая туда информацию об исключениях, если они были. Именно в __exit__ и происходит освобождение ресурса (закрытие файла).

  

Оператор with — это стандарт де-факто для управления ресурсами в Python. Он делает код не только короче, но и значительно безопаснее и понятнее.