Как python закрывает файлы, которые были gc'ed?

Я всегда предполагал, что файл будет протекать, если он был открыт, но не был закрыт, но я просто подтвердил, что если я введу следующие строки кода, файл закроется:

>>> f = open('somefile.txt')
>>> del f

Просто из чистого любопытства, как это работает? Я замечаю, что файл не включает метод __ del __.

Ответ 1

В CPython, по крайней мере, файлы закрываются, когда файл-объект освобождается. См. Функцию file_dealloc в Objects/fileobject.c в источнике CPython. Методы Dealloc являются похожими на __del__ для типов C, за исключением тех, которые не присущи __del__.

Ответ 2

Следовательно, оператор с.

Для Python 2.5 используйте

from __future__ import with_statement

(для Python 2.6 или 3.x ничего не делать)

with open( "someFile", "rU" ) as aFile:
    # process the file
    pass
# At this point, the file was closed by the with statement.
# Bonus, it also out of scope of the with statement,
# and eligible for GC.

Ответ 3

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

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

Обратите внимание, что подсчет ссылок не является совершенным. У вас могут быть объекты с круглыми ссылками, которые недоступны для прогаммы. Вот почему Python имеет сбор мусора в дополнение к подсчету ссылок.

Ответ 4

Лучше предположить, что, поскольку тип файла является встроенным типом, сам интерпретатор обрабатывает закрытие файла в сборке мусора.

Кроме того, вы проверяете только после выхода из интерпретатора python, и все "пропущенные" дескрипторы файлов все равно закрыты.