В Python, если вы открываете файл без вызова close()
или закрываете файл, но не используете try
- finally
или with
оператор " ", это проблема? Или для практики кодирования достаточно полагаться на сборку мусора Python для закрытия всех файлов? Например, если кто-то делает это:
for line in open("filename"):
# ... do stuff ...
... это проблема, потому что файл никогда не может быть закрыт и может возникнуть исключение, которое не позволяет закрыть его? Или он обязательно будет закрыт по завершении for
утверждения, потому что файл выходит из области видимости?
python
file
garbage-collection
user553702
источник
источник
for
блока. Его счетчик ссылок станет равным нулю, что приведет к его автоматическому закрытию, но только области, классы и модули определяют области в Python, а не другие составные операторы.for
блоками и функциями / классами / модулями. Это гораздо проще: объекты не имеют границ, только имена. Нет имени, которое ссылается на этот объект, поэтому здесь нет ничего, что могло бы оставаться в области видимости или выходить из области видимости.for
циклом связана область видимости , и упоминает, что файл закрывается по совершенно другой причине. Это не касается того, что является областью действия в Python, так как здесь это не актуально.Ответы:
В вашем примере файл не гарантированно будет закрыт до выхода из интерпретатора. В текущих версиях CPython файл будет закрыт в конце цикла for, потому что CPython использует подсчет ссылок в качестве основного механизма сборки мусора, но это деталь реализации, а не особенность языка. Другие реализации Python не гарантированно будут работать таким образом. Например, IronPython, PyPy и Jython не используют подсчет ссылок и поэтому не будут закрывать файл в конце цикла.
Неправильно полагаться на реализацию сборки мусора CPython, потому что она делает ваш код менее переносимым. Возможно, у вас не будет утечек ресурсов, если вы используете CPython, но если вы когда-нибудь переключитесь на реализацию Python, которая не использует подсчет ссылок, вам нужно будет просмотреть весь ваш код и убедиться, что все ваши файлы закрыты должным образом.
Для вашего примера используйте:
источник
with open() as f
автоматически закрывает файл после того, как это сделано?with
обеспечивает оператор, но, конечно, чтобы эта магия работала, объект должен иметь особые методы,__enter__
а__exit__
в последнем объект выполняет теclose
или иные другие действия по очистке, которые необходимо выполнить на конецwith
заявления ...Некоторые Pythons автоматически закрывают файлы, когда на них больше нет ссылок, в то время как другие этого не делают, и это зависит от O / S, чтобы закрыть файлы при выходе из интерпретатора Python.
Даже для Питонов, которые будут закрывать файлы для вас, время не гарантируется: это может быть немедленно, или это могут быть секунды / минуты / часы / дни спустя.
Таким образом, хотя у вас могут не возникнуть проблемы с Python, который вы используете, не рекомендуется оставлять файлы открытыми. Фактически, в cpython 3 теперь вы будете получать предупреждения о том, что система должна была закрыть для вас файлы, если вы этого не сделали.
Мораль: Приведи себя в порядок. :)
источник
Хотя в данном конкретном случае использование такой конструкции вполне безопасно, существуют некоторые предостережения для обобщения такой практики:
источник
Файл получает мусор, и, следовательно, закрывается. GC определяет, когда он закроется, а не вы. Очевидно, что это не рекомендуемая практика, потому что вы можете достичь предела количества открытых файлов, если не закрываете файлы, как только заканчиваете их использовать. Что если в этом
for
цикле вы откроете больше файлов и оставите их в покое?источник
for
оператора - вам не придется ждать следующего запуска сборки мусора.Привет Очень важно закрыть свой файловый дескриптор в ситуации, когда вы собираетесь использовать его содержимое в том же скрипте Python. Я сегодня сама осознаю после столь долгой нерешительной отладки. Причина в том, что контент будет отредактирован / удален / сохранен только после того, как вы закроете дескриптор файла и изменения будут затронуты файлом!
Предположим, у вас есть ситуация, когда вы записываете контент в новый файл, а затем, не закрывая fd, используете этот файл (не fd) в другой команде оболочки, которая читает его содержимое. В этой ситуации вы не сможете получить содержимое для команды оболочки, как ожидалось, и если вы попытаетесь отладить, вы не сможете легко найти ошибку. Вы также можете прочитать больше в моей записи в блоге http://magnificentzps.blogspot.in/2014/04/importance-of-closing-file-descriptor.html
источник
Во время процесса ввода / вывода данные буферизуются: это означает, что они хранятся во временном местоположении перед записью в файл.
Python не очищает буфер, то есть записывает данные в файл, пока не будет уверен, что вы закончили запись. Один из способов сделать это - закрыть файл.
Если вы пишете в файл без закрытия, данные не попадут в целевой файл.
источник