Python использует подсчет ссылок и детерминированное уничтожение в дополнение к сборке мусора. Когда больше нет ссылок на объект, объект немедленно освобождается. Выпуск файла закрывает его.
Это отличается, например, от Java, где есть только недетерминированная сборка мусора. Это означает, что вы не знаете, когда объект будет освобожден, поэтому вам придется закрыть файл вручную.
Обратите внимание, что подсчет ссылок не идеален. Вы можете иметь объекты с круговыми ссылками, которые недоступны из программы. Вот почему в Python есть сборщик мусора в дополнение к подсчету ссылок.