Пользовался 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_ (сессии, соединения), — есть простая мысль «гарантированно освободить». Одна из задач типа «я наконец понял, а не вызубрил».