В Python, если вы либо открываете файл без вызова close(), либо закрываете файл, но не используете оператор try-finally или "with", является ли это проблемой? Или в качестве практики программирования достаточно полагаться на сборку мусора Python для закрытия всех файлов? Например, если сделать это:
for line inopen("filename"): # ... do stuff ...
... это проблема из-за того, что файл никогда не может быть закрыт и может возникнуть исключение, препятствующее его закрытию? Или он определенно будет закрыт по завершении for инструкции, потому что файл выходит за пределы области видимости?
Переведено автоматически
Ответ 1
В вашем примере не гарантируется закрытие файла до завершения работы интерпретатора. В текущих версиях CPython файл будет закрыт в конце цикла for, потому что CPython использует подсчет ссылок в качестве основного механизма сборки мусора, но это деталь реализации, а не особенность языка. Другие реализации Python не гарантированно будут работать таким образом. Например, IronPython, PyPy и Jython не используют подсчет ссылок и, следовательно, не будут закрывать файл в конце цикла.
Полагаться на реализацию сборки мусора CPython - плохая практика, потому что это делает ваш код менее переносимым. Утечки ресурсов может и не быть, если вы используете CPython, но если вы когда-нибудь переключитесь на реализацию Python, которая не использует подсчет ссылок, вам нужно будет просмотреть весь ваш код и убедиться, что все ваши файлы закрыты должным образом.
Для вашего примера используйте:
withopen("filename") as f: for line in f: # ... do stuff ...
Ответ 2
Некоторые Pythons автоматически закроют файлы, когда на них больше не будет ссылок, в то время как другие этого не сделают, и это зависит от операционной системы, которая закрывает файлы при завершении работы интерпретатора Python.
Даже для Pythons, которые закроют файлы за вас, время не гарантировано: это может произойти немедленно, или это могут быть секунды / минуты / часы / дни спустя.
Итак, хотя вы можете не испытывать проблем с используемым вами Python, оставлять ваши файлы открытыми определенно не рекомендуется. Фактически, в cpython 3 теперь вы будете получать предупреждения о том, что системе пришлось закрыть файлы за вас, если вы этого не сделали.
Мораль: убирайте за собой. :)
Ответ 3
Хотя в данном конкретном случае использовать такую конструкцию вполне безопасно, есть некоторые предостережения для обобщения такой практики:
при запуске потенциально могут закончиться файловые дескрипторы, хотя это маловероятно, представьте, что вы ищете подобную ошибку
возможно, вы не сможете удалить указанный файл в некоторых системах, например, win32
если вы запускаете что-либо другое, кроме CPython, вы не знаете, когда файл будет закрыт для вас
если вы открываете файл в режиме записи или чтения-записи, вы не знаете, когда данные будут сброшены
Ответ 4
Файл действительно собирает мусор и, следовательно, закрывается. GC определяет, когда он будет закрыт, а не вы. Очевидно, что это не рекомендуемая практика, потому что вы можете достичь предела дескриптора открытого файла, если не закроете файлы сразу после завершения их использования. Что, если в этом вашем for цикле вы откроете больше файлов и оставите их отложенными?