2016-09-16 1 views
4

Если я (в Python):Является ли файл автоматически закрытым, если он читается в той же строке, что и открытие?

text = open("filename").read() 

является файл автоматически закрыт?

+0

open вернет дескриптор файла. так как вы никогда не захватываете этот дескриптор, даже если файл остается открытым, вам нечего читать. –

ответ

6

Сборщик мусора будет активирован в какой-то момент, но вы не можете быть уверены в том, когда, если вы его не нажмете.

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

with open("filename") as f: text = f.read() 

также один вкладыш, но безопаснее.

3

В CPython (эталонная реализация Python) файл будет автоматически закрыт. CPython уничтожает объекты, как только у них нет ссылок, что происходит в конце инструкции в самое последнее время.

В других реализациях Python это может не произойти сразу же, поскольку они могут полагаться на управление памятью базовой виртуальной машины или использовать какую-либо другую стратегию управления памятью (см. PyParallel для интересного примера).

Язык Python не указывает какую-либо конкретную форму управления памятью, поэтому вы не можете полагаться на файл, закрываемый в общем случае. Используйте оператор with, чтобы явно указать, когда он будет закрыт, если вам нужно полагаться на него.

На практике я часто использую этот подход в короткоживущих сценариях, где это не имеет большого значения, когда файл закрывается.

+0

Вы уверены, что часть «в конце заявления»? И если да, то как, могу я спросить? – martineau

+1

CPython освобождает объекты, когда их счетчик ссылок достигает нуля. Это не делается явно в конце заявления (это было упрощение, и я немного пересмотрел свой ответ). 'read()' в файле содержит ссылку на файл, но как только это возвращается, ссылки на файл отсутствуют, поэтому он уходит. Я уверен в этом, потому что CPython документирован как использование подсчета ссылок (с дополнительной сборкой мусора для очистки эталонных циклов), и именно так работает подсчет ссылок. – kindall

+0

Я знаю, как работает подсчет ссылок, но мой опыт работы с сборщиком мусора заключается в том, что невозможно предсказать, когда он будет вызван (если вы не сделаете это сами, конечно). Поэтому я беру исключение из вашего заявления. – martineau

2

Поскольку у вас нет ссылки на дескриптор открытого файла, CPython автоматически закрывает его либо во время сбора мусора, либо при выходе из программы. Проблема здесь в том, что у вас нет никаких гарантий относительно того, когда это произойдет, поэтому конструкция with open(...) является предпочтительной.

Смежные вопросы