Важно ли явно закрывать файлы? - PullRequest
135 голосов
/ 13 сентября 2011

В Python, если вы открываете файл без вызова close() или закрываете файл, но не используете try - finally или оператор "with", это проблема? Или для практики кодирования достаточно полагаться на сборку мусора Python для закрытия всех файлов? Например, если кто-то делает это:

for line in open("filename"):
    # ... do stuff ...

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

Ответы [ 6 ]

117 голосов
/ 13 сентября 2011

В вашем примере файл не гарантированно будет закрыт до выхода из интерпретатора. В текущих версиях CPython файл будет закрыт в конце цикла for, потому что CPython использует подсчет ссылок в качестве основного механизма сборки мусора, но это деталь реализации, а не особенность языка. Другие реализации Python не гарантированно будут работать таким образом. Например, IronPython, PyPy и Jython не используют подсчет ссылок и поэтому не закрывают файл в конце цикла.

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

Для вашего примера используйте:

with open("filename") as f:
     for line in f:
        # ... do stuff ...
22 голосов
/ 13 сентября 2011

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

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

Так что, хотя у вас могут не возникнуть проблемы с Python, который вы используете, онЭто определенно не очень хорошая практика оставлять ваши файлы открытыми.На самом деле, в cpython 3 теперь вы будете получать предупреждения о том, что система должна была закрыть файлы для вас, если вы этого не сделали.

Мораль: Очистите себя.:)

9 голосов
/ 28 июня 2013

Несмотря на то, что в данном конкретном случае использовать такую ​​конструкцию довольно безопасно, существуют некоторые предостережения для обобщения такой практики:

  • В прогоне потенциально могут быть исчерпаны файловые дескрипторы, хотя маловероятно, что представьте себе охоту наошибка типа
  • вы не сможете удалить указанный файл в некоторых системах, например, win32
  • , если вы запускаете что-то кроме CPython, вы не знаете, когда файл будет закрыт для вас
  • если вы открываете файл в режиме записи или чтения-записи, вы не знаете, когда данные сбрасываются
3 голосов
/ 30 апреля 2014

Привет Очень важно закрыть свой файловый дескриптор в ситуации, когда вы собираетесь использовать его содержимое в том же скрипте Python.Я сегодня сама осознаю после столь долгой нерешительной отладки.Причина в том, что контент будет редактироваться / удаляться / сохраняться только после того, как вы закроете дескриптор файла, и изменения будут затронуты в файле!

Итак, предположим, что у вас есть ситуация, когда вы пишете контент в новый файл, а затем не закрываете его.используете этот файл (не fd) в другой команде оболочки, которая читает его содержимое.В этой ситуации вы не сможете получить содержимое для команды оболочки, как ожидалось, и если вы попытаетесь отладить, вы не сможете легко найти ошибку.Вы также можете прочитать больше в моей записи в блоге http://magnificentzps.blogspot.in/2014/04/importance-of-closing-file-descriptor.html

3 голосов
/ 13 сентября 2011

Файл получает мусор и, следовательно, закрывается. GC определяет, когда он закроется, а не вы. Очевидно, что это не рекомендуемая практика, потому что вы можете достичь предела количества открытых файлов, если не закрываете файлы, как только заканчиваете их использовать. Что если в этом цикле for вы откроете больше файлов и оставите их в покое?

1 голос
/ 28 сентября 2018

Во время процесса ввода / вывода данные буферизуются: это означает, что они хранятся во временном местоположении перед записью в файл.

Python не очищает буфер, то есть записывает данные в файл, пока не будет уверен, что вы закончили запись. Один из способов сделать это - закрыть файл.

Если вы записываете в файл без закрытия, данные не попадают в целевой файл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...