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

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

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

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

Ответ 1

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

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

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

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

Ответ 2

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

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

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

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

Ответ 3

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

  • run может потенциально закончиться файловыми дескрипторами, хотя и маловероятно, представьте, что вы ищете такую ​​ошибку.
  • вы не сможете удалить указанный файл в некоторых системах, например. win32
  • Если вы запускаете что-либо, кроме CPython, вы не знаете, когда файл закрыт для вас.
  • Если вы открываете файл в режиме записи или чтения-записи, вы не знаете, когда данные сбрасываются.

Ответ 4

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

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

Ответ 5

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