Пользовался with для файлов, не понимая механики, и немного стыдно за «магию». Потом разобрал _enter_/_exit_ и увидел: with гарантирует уборку даже при ошибке. Механика простая, а слово «контекст-менеджер» перестало пугать.
Нейтрально: контекст-менеджер даёт код до и после блока «с гарантией», даже если посередине упало. Классика — открытие файла с авто-закрытием.
class safe_resource:
def __enter__(self):
print("открываем")
return self
def __exit__(self, exc_type, exc, tb):
print("закрываем, даже если упали")
with safe_resource() as r:
raise ValueError("промежуток")
# 'всегда закрываем' напечатается благодаря __exit__
Свеча из облегчения: разобрал механизм «за кулисами», и код перестал быть шаманством. Когда пойму, когда сам захочу _enter_/_exit_ (сессии, соединения), — есть простая мысль «гарантированно освободить». Одна из задач типа «я наконец понял, а не вызубрил».