Если вы читаете весь файл с content = open('Path/to/file', 'r').read()
помощью, останется ли дескриптор файла открытым до завершения работы сценария? Есть ли более краткий способ прочитать весь файл?
Если вы читаете весь файл с content = open('Path/to/file', 'r').read()
помощью, останется ли дескриптор файла открытым до завершения работы сценария? Есть ли более краткий способ прочитать весь файл?
Ответ на этот вопрос зависит от конкретной реализации Python.
Чтобы понять, о чем это все, обратите особое внимание на реальный file
объект. В вашем коде этот объект упоминается только один раз в выражении и становится недоступным сразу после read()
возврата вызова.
Это означает, что файловый объект является мусором. Единственный оставшийся вопрос - «Когда сборщик мусора соберет объект файла?».
в CPython, который использует счетчик ссылок, этот вид мусора замечается немедленно, и поэтому он будет немедленно собран. Обычно это не так для других реализаций Python.
Лучшее решение, чтобы убедиться, что файл закрыт, это шаблон:
with open('Path/to/file', 'r') as content_file:
content = content_file.read()
который всегда будет закрывать файл сразу после окончания блока; даже если происходит исключение.
Редактировать: чтобы поставить более тонкую точку на нем:
Кроме того file.__exit__()
, что «автоматически» вызывается в with
настройке диспетчера контекста, единственный другой способ, который file.close()
вызывается автоматически (то есть, кроме явного его вызова самостоятельно), - через file.__del__()
. Это приводит нас к вопросу о том, когда звонят __del__()
?
Правильно написанная программа не может предполагать, что финализаторы когда-либо будут работать в любой момент до завершения программы.
- https://devblogs.microsoft.com/oldnewthing/20100809-00/?p=13203
В частности:
Объекты никогда не уничтожаются явно; однако, когда они становятся недоступными, они могут быть собраны мусором. Реализация может откладывать сборку мусора или вообще ее опускать - это вопрос качества реализации, как осуществляется сборка мусора, если не собраны объекты, которые все еще доступны.
[...]
CPython в настоящее время использует схему подсчета ссылок с (опционально) отложенным обнаружением циклически связанного мусора, который собирает большинство объектов, как только они становятся недоступными, но не гарантирует сбор мусора, содержащего циклические ссылки.
- https://docs.python.org/3.5/reference/datamodel.html#objects-values-and-types
(Акцент мой)
но, как предполагается, другие реализации могут иметь другое поведение. Например, в PyPy есть 6 разных реализаций сборки мусора !
__exit__()
в таких случаях звучит как недостаток дизайна.try
/ из-заfinally
того , что он неуклюжий и чрезвычайно распространенный бесполезный из обработчиков очистки, которыйwith
решается. Разница между «явным закрытием» и «управлением сwith
» заключается в том, что обработчик выхода вызывается, даже если выдается исключение. Вы могли бы поместитьclose()
вfinally
предложение, но это не сильно отличается от использованияwith
вместо этого, немного более грязный (3 дополнительные строки вместо 1), и немного сложнее сделать правильно.with foo() as f: [...]
в основном то же самоеf = foo()
, чтоf.__enter__()
, [...] иf.__exit__()
с обработанными исключениями , так что__exit__
всегда вызывается. Таким образом, файл всегда закрывается.Вы можете использовать pathlib .
Для Python 3.5 и выше:
Для более старых версий Python используйте pathlib2 :
Затем:
Это фактическая
read_text
реализация :источник
Ну, если вам нужно читать файл построчно для работы с каждой строкой, вы можете использовать
Или еще лучше
источник
Вместо извлечения содержимого файла в виде одной строки может быть удобно сохранить содержимое в виде списка всех строк, которые содержит файл :
Как видно, нужно добавить сцепленные методы
.strip().split("\n")
к основному ответу в этой теме .Здесь
.strip()
просто удаляются пробелы и символы новой строки в конце всей строки файла, и.split("\n")
создается фактический список путем разделения всей строки файла на каждый символ новой строки \ n .Более того, таким образом все содержимое файла может храниться в переменной, которая может быть желательна в некоторых случаях, вместо того, чтобы циклически перемещаться по файлу, как указывалось в предыдущем ответе .
источник