Файл закрыть: Метод file.close() в Python, закрывает файл
Содержание
Закрыть файл | Работа в МойОфис Текст Настольная версия
Создать файлСоздать шаблон файлаСоздать файл из шаблонаОткрыть файлОткрыть недавние документыОткрыть файл в другом приложенииСохранить файлОтправить файл по почтеЭкспортировать файлРаспечатать документ без входа в приложениеРаспечатать документЗакрыть файл
Создать файл
Создать шаблон файла
Создать файл из шаблона
Открыть файл
Открыть недавние документы
Открыть файл в другом приложении
Сохранить файл
Отправить файл по почте
Экспортировать файл
Распечатать документ без входа в приложение
Распечатать документ
Закрыть файл
Продукт: МойОфис Профессиональный, МойОфис Стандартный, МойОфис Образование, МойОфис Текст
После завершения работы с файлом сохраните его и закройте окно приложения одним из следующих способов:
•Выберите пункт командного меню Файл > Закрыть.
•Нажмите кнопку Закрыть в заголовке окна приложения.
•Нажмите сочетание клавиш Alt+F4.
Поделиться:
Был ли материал полезным?
Пользователи, считающие этот материал полезным: 0 из 0
Предыдущее
Почему важно закрывать файлы в Python? • Школа программирования Pylot.me
Python
Alexander Lukyanov
2022-10-11
Чем чреваты файлы, своевременно не закрытые в операционной системе
При создании программного обеспечения с функциями обработки файлов, у вас всегда есть риск получения ошибки операционной системы (ОС) типа ‘Too many open files’ – слишком много открытых файлов. Это объясняется тем, что количество открытых файлов, как и любой другой ресурс для ОС всегда является ограниченным. Конечно, в теории современные компьютеры способны одновременно обрабатывать сотни тысяч, а то и миллионы открытых файлов. Но реально, следует учитывать, что с нарастанием функциональных возможностей и сервисов ОС, их контроль должен распределяться на все большое количество технических параметров и возможностей компьютера. Следовательно, удельный вес ресурсов, отведенных в ОС на работу с файлами, снижается. Так, на примере нижеприведенного фрагмента Python программы можно увидеть, что даже количество в несколько десятков тысяч одновременно открытых файлов, далеко не всегда приемлемо для современных ОС и компьютеров:
>>> files = [open(f"file-{n}.txt", mode="w") for n in range(10000)] Traceback (most recent call last): ... OSError: [Errno 24] Too many open files: 'file-1021.txt'
Данный фрагмент пытается открыть десять тысяч файлов и сохранить их на диске. Но, в итоге ОС выдает ошибку Too many open files, как только лимит одновременно открытых файлов в ней исчерпывается. Более того, реально созданное на диске количество файлов зачастую может и не совпадать с тем, что выдается сообщением об ошибке при сбои вышеприведенной программы.
Рекомендации: С целью предотвращения мешанины среди вновь создаваемых и уже имеющихся файлов на диске, вышеприведенную программу желательно запускать в предварительно созданной директории. Для UNIX-подобных ОС это реализуется следующими командами:
$ mkdir file_experiment $ cd file_experiment
Превышение лимита одновременно открытых файлов довольно часто также сопровождается блокированием файлов, когда помимо того, что в них невозможно ничего записать, эти файлы еще и невозможно ни удалить, ни переместить. В этом случае вам скорее всего придется пересматривать тысячи, а то и десятки тысяч файлов на предмет того, не являются ли они пустыми и, можно ли их удалить.
Для борьбы с проблемами, вызванными несвоевременным закрытие файлов в Python предусмотрен ряд соответствующих механизмов. Но для того, чтобы более подробно остановится на них, нам предварительно понадобится рассмотреть процесс взаимодействия Python и ОС при работе с файлами.
Что такое «Файловые дескрипторы» и, для чего они используются
Базовая функция любой ОС состоит в обеспечении посредничества между прикладными программными процессами, такими как Python и, различными системными ресурсами вроде жестких дисков, оперативной памяти и процессорного времени.
Следовательно, открывая на Python определенный файл с помощью функции open(), вы на самом деле осуществляете системный вызов операционной системе, с тем чтобы найти этот файл на информационном носителе, а также подготовить его для чтения или записи. В итоге ОС возвращает в Python целое число без знака, называемое в Windows — file handle, а в UNIX-подобных системах типа Linux и macOS — file descriptor:
Рис. 1. Процесс Python, выполняющий системный вызов и получающий целое число 10 в качестве дескриптора файла.
Впоследствии, полученное вами целое число в виде номера файлового дескриптора должно использоваться программой Python всякий раз, когда ей нужно прочитать, записать или закрыть соответствующий файл. Это делается путем еще одного вызова ОС, где указывается номер соответствующего дескриптора, нужного для работы файла. Хотя непосредственное значение файлового дескриптора для конкретных файлов в виде целого числа редко необходимо в Python программах, его все же можно узнать, воспользовавшись методом файлового объекта — . fileno():
>>> with open("test_file.txt", mode="w") as file: ... file.fileno() ... 4
Применение механизмов, обеспечивающих своевременное закрытие файлов
Как уже было сказано, в Python существует множество механизмов, предотвращающих ошибки из-за отставленных открытыми файлов и соответственно, обеспечивающих своевременное закрытие тех файлов, которые использовались программой. Все эти механизмы, как правило, обеспечивают автоматическое закрытие файлов при завершении всей программы, либо каких-то ее процессов за счет использования вышеописанных файловых дескрипторов. Так, например, при выполнении этого кода:
# write_hello.py file = open("hello.txt", mode="w") file.write("Hello, world!")
Python после создания файла hello.txt и записи в него текста ‘Hello, world!’ сам заботиться о том, чтобы этот файл был автоматически закрыт после благополучного завершения программы.
Однако, что, если данная программа не завершится корректно, например, из-за отключения электричества в момент ее выполнения? Смоделируем эту ситуацию программным путем за счет применения функции os. _exit(1), имитирующей сбой программы:
# crash_hello.py import os file = open("crash.txt", mode="w") file.write("Hello, world!") os._exit(1)
Результат выполнения последнего фрагмента кода можно посмотреть путем вывода содержимого файла ‘ crash.txt’, используя команду cat (для UNIX-систем):
$ cat crash.txt $ # No output!
Как видим, что хотя вышеназванный файл и был создан ОС, но он оказался пустым.
Таким образом, при написании программ лучше все же закрывать файлы сразу после того, как они были использованы. Это можно сделать путем использования конструкции try… finally:
try: file = open("hello.txt", mode="w") file.write("Hello, World!") finally: file.close()
Где блок finally безальтернативно закрывает файл ‘hello.txt’ независимо от того, успешно ли был выполнен блок try. Вмести с тем, использования конструкции try… finally для своевременного закрытия файлов является довольно громоздким и трудночитаемым. Гораздо более компактный и интуитивно понятный подход в Python обеспечивается применением так называемого контекстного менеджера, благодаря которому вышеприведенный код выглядит следующим образом:
with open("hello.txt", mode="w") as file: file.write("Hello, World!")
Первой строкой в этом коде (оператором with) инициируется контекстный менеджер — блок, все последующие строки которого являются строками с отступом. Как только эти строки с отступом заканчиваются или же при их выполнении вызывается какое-либо исключение, файлы, обрабатываемые в данном контекстном менеджере, закрываются. Таким образом программы, написанные с использованием подобных менеджеров компактны, интуитивно понятны и читабельны.
Выводы
Поскольку файлы являются ограниченными ресурсами, управляемыми ОС, то при работе с ними всегда существует опасность возникновения трудно отлаживаемых программных сбоев, связанных либо с исчерпанием лимита ОС для файловых дескрипторов, либо просто с повреждением данных при их сохранении на диске. Поэтому во избежание таких ситуаций в Python предусмотрена масса механизмов, среди которых лучшим вариантом является применение соответствующего контекстного менеджера.
Практический Python для начинающих
Станьте junior Python программистом за 7 месяцев
7 месяцев
Подробнее
Как открыть и закрыть файл в Python
Может возникнуть ситуация, когда нужно взаимодействовать с внешними файлами с помощью Python. Python предоставляет встроенные функции для создания, записи и чтения файлов. В этой статье мы обсудим, как открыть внешний файл и закрыть его с помощью Python.
Открытие файла в Python
Существует два типа файлов, которые можно обрабатывать в Python: обычные текстовые файлы и двоичные файлы (написанные на двоичном языке, 0 и 1). Открытие файла относится к подготовке файла либо к чтению, либо к записи. Это можно сделать с помощью функция open() . Эта функция возвращает файловый объект и принимает два аргумента, один из которых принимает имя файла, а другой принимает режим (режим доступа).
Примечание: Файл должен находиться в том же каталоге, что и скрипт Python, в противном случае необходимо записать полный адрес файла.
Синтаксис: File_object = open(«File_Name», «Access_Mode»)
Параметры:
- File_Name: Это имя файла, который необходимо открыть.
- Access_Mode: Режимы доступа определяют тип операций, возможных в открытом файле. В таблице ниже приведен список всех режимов доступа, доступных в Python
Операция | Синтаксис | Описание |
---|---|---|
Чтение Только | r | Открыть текстовый файл только для чтения. |
Чтение и запись | r+ | Открыть файл для чтения и записи. |
Только запись | w | Открыть файл для записи. |
Запись и чтение | w+ | Открыть файл для чтения и записи. В отличие от «r+», это не вызывает ошибку ввода-вывода, если файл не существует. |
Добавить только | a | Открыть файл для записи и создать новый файл, если он не существует. Все дополнения делаются в конце файла, и никакие существующие данные не могут быть изменены. |
Добавить и прочитать | a+ | Открыть файл для чтения и записи и создать новый файл, если он не существует. Все дополнения делаются в конце файла, и никакие существующие данные не могут быть изменены. |
Пример 1: Открыть и прочитать файл с помощью Python
В этом примере мы будем открывать файл только для чтения. Исходный файл выглядит следующим образом:
Код:
Python3
файл = открыть ( "sample.txt" )
|
Здесь мы открыли файл и распечатал его содержимое.
Вывод:
Привет, Компьютерщик! Это образец текстового файла для примера.
Пример 2: Открытие и запись в файл с помощью Python
В этом примере мы будем добавлять новое содержимое к существующему файлу. Таким образом, исходный файл выглядит следующим образом:
Код:
Python3
файл = открыть ( "sample.txt" , 'a' )
|
Теперь, если вы откроете файл, вы увидите следующий результат:
Вывод:
9010 1 Пример 3: Открыть и перезаписать файл с помощью Python.
файл
=
открыть
(
"sample.txt"
,
'w'
)
файл
.write(
"Все содержимое было перезаписано!"
)
Приведенный выше код приводит к следующему результату:
Вывод: 9000 3
Пример 4. Создание файла, если он не существует в Python
Метод path.touch() модуля pathlib создает файл по пути, указанному в пути path.touch().
Python3
из pathlib импорт Path
|
Выход:
Закрытие файла в Python
Как вы заметили, мы не закрыли ни один из файлов, над которыми мы работали в приведенных выше примерах. Хотя Python автоматически закрывает файл, если ссылочный объект файла выделяется для другого файла, стандартная практика — закрытие открытого файла, поскольку закрытый файл снижает риск необоснованного изменения или чтения.
Python имеет метод close() для закрытия файла. Метод close() можно вызывать более одного раза, и если какая-либо операция выполняется с закрытым файлом, возникает ошибка ValueError. В приведенном ниже коде показано простое использование метода close() для закрытия открытого файла.
Пример: Прочитайте и закройте файл с помощью Python
Python3
файл = открыть 901 21 |
Теперь, если мы попытаемся выполнить какую-либо операцию на закрытый файл, как показано ниже, вызывает ошибку ValueError:
Python3
файл = открыть ( "sample. txt" )
|
Вывод:
ValueError: Операция ввода/вывода в закрытом файле.
Почему важно закрывать файлы в Python? – Real Python
В какой-то момент вашего пути к написанию кода на Python вы узнаете, что для открытия файлов следует использовать контекстный менеджер . Менеджеры контекста Python упрощают закрытие ваших файлов после того, как вы закончите с ними:
с помощью open("hello.txt", mode="w") в качестве файла: file.write("Привет, мир!")
Оператор с оператором
инициирует диспетчер контекста. В этом примере диспетчер контекста открывает файл hello. txt
и управляет файловым ресурсом, пока активен контекст . В общем, весь код в блоке с отступом зависит от того, какой файловый объект открыт. Как только блок с отступом заканчивается или вызывает исключение, файл закрывается.
Если вы не используете диспетчер контекста или работаете на другом языке, вы можете явно закрыть файлы с помощью попытка
… наконец
подход:
попытка: файл = открыть ("hello.txt", режим = "w") file.write("Привет, мир!") окончательно: файл.закрыть()
Блок finally
, который закрывает файл, выполняется безоговорочно, независимо от того, успешен или нет блок try
. Хотя этот синтаксис эффективно закрывает файл, менеджер контекста Python предлагает менее подробный и более интуитивно понятный синтаксис. Кроме того, это немного более гибко, чем просто обертывание вашего кода попробовать
… наконец
.
Вероятно, вы уже используете контекстные менеджеры для управления файлами, но задумывались ли вы когда-нибудь, почему большинство руководств и четыре из пяти стоматологов рекомендуют это делать? Короче говоря, почему важно закрывать файлы в Python?
В этом уроке вы погрузитесь в этот вопрос. Во-первых, вы узнаете, что дескрипторы файлов являются ограниченным ресурсом . Затем вы поэкспериментируете с последствиями незакрытия ваших файлов.
Вкратце: файлы — это ресурсы, ограниченные операционной системой
Python делегирует файловые операции операционной системе . Операционная система является посредником между процессами , такими как Python, и всеми системными ресурсами , такими как жесткий диск, оперативная память и процессорное время.
Когда вы открываете файл с помощью open()
, вы делаете системный вызов в операционную систему, чтобы найти этот файл на жестком диске и подготовить его для чтения или записи. Затем операционная система вернет целое число без знака, называемое 9.дескриптор файла 0005 в Windows и дескриптор файла в UNIX-подобных системах, включая Linux и macOS:
Процесс Python выполняет системный вызов и получает целое число 10 в качестве дескриптора файла
. Когда у вас есть число, связанное с файлом, вы готовы выполнять операции чтения или записи. Всякий раз, когда Python хочет прочитать, записать или закрыть файл, он сделает еще один системный вызов, предоставив номер дескриптора файла. Файловый объект Python имеет метод .fileno()
, который можно использовать для поиска дескриптора файла:
>>>
>>> с open("test_file.txt", mode="w") в качестве файла: ... файл.fileno() ... 4
Метод .fileno()
для открытого файлового объекта вернет целое число, используемое операционной системой в качестве файлового дескриптора. Точно так же, как вы можете использовать поле идентификатора для получения записи из базы данных, Python предоставляет этот номер операционной системе каждый раз, когда она читает или записывает файл.
Операционные системы ограничивают количество открытых файлов, которые может иметь один процесс . Обычно это число исчисляется тысячами. Операционные системы устанавливают это ограничение, потому что, если процесс пытается открыть тысячи файловых дескрипторов, вероятно, что-то не так с процессом. Несмотря на то, что тысячи файлов могут показаться большим количеством, все же можно достичь предела.
Помимо риска превышения лимита, сохранение файлов открытыми делает вас уязвимыми к потере данных . В общем, Python и операционная система прилагают все усилия, чтобы защитить вас от потери данных. Но если ваша программа или компьютер выйдет из строя, обычные процедуры могут не выполняться, а открытые файлы могут быть повреждены.
Примечание : Некоторые библиотеки имеют специальные методы и функции, которые, кажется, открывают файлы без менеджера контекста. Например, в библиотеке pathlib есть .write_text()
, а в pandas — read_csv()
.
Однако они правильно управляют ресурсами внутри, поэтому в таких случаях вам не нужно использовать контекстный менеджер. Лучше всего обратиться к документации по библиотеке, которую вы используете, чтобы узнать, нужен вам контекстный менеджер или нет.
Короче говоря, разрешение контекстным менеджерам управлять вашими файлами — это защитная техника, которую легко практиковать, и она делает ваш код лучше, так что вы тоже можете это сделать. Это как пристегиваться ремнем безопасности. Вероятно, вам это не понадобится, но затраты на то, чтобы обойтись без него, могут быть высокими.
В оставшейся части этого руководства вы более глубоко познакомитесь с ограничениями, последствиями и опасностями незакрытия файлов. В следующем разделе вы изучите ошибку Слишком много открытых файлов
.
Удалить рекламу
Что происходит, когда вы открываете слишком много файлов?
В этом разделе вы узнаете, что происходит, когда вы достигаете предела файлов. Вы сделаете это, попробовав фрагмент кода, который создаст множество открытых файлов и спровоцирует Ошибка ОС
.
Примечание : как предполагает OS
в OSError
, ограничение применяется операционной системой, а не Python. Однако теоретически операционная система может работать с гораздо большим количеством файловых дескрипторов. Позже вы узнаете больше о том, почему операционная система ограничивает дескрипторы файлов.
Вы можете проверить лимит файлов на процесс в вашей операционной системе, попытавшись одновременно открыть тысячи файлов. Вы сохраните файловые объекты в списке, чтобы они не очищались автоматически. Но сначала вам нужно сделать некоторую уборку, чтобы убедиться, что вы не создаете много файлов там, где они вам не нужны:
$ mkdir file_experiment $ cd file_experiment
Достаточно создать папку, в которую можно сбросить файлы, а затем перейти в эту папку. Затем вы можете открыть Python REPL и попытаться создать тысячи файлов:
>>>
>>> files = [open(f"file-{n}.txt", mode="w") для n в диапазоне (10_000)] Traceback (последний последний вызов): ... OSError: [Errno 24] Слишком много открытых файлов: «file-1021.txt»
Этот фрагмент пытается открыть десять тысяч файлов и сохранить их в списке. Операционная система начинает создавать файлы, но отбрасывает их, как только достигает своего предела. Если вы перечислите файлы во вновь созданном каталоге, вы заметите, что даже несмотря на то, что понимание списка в конечном итоге дало сбой, операционная система создала многие из файлов — но не те десять тысяч, которые вы просили.
Ограничение, с которым вы столкнетесь, зависит от операционной системы и кажется больше по умолчанию в Windows. В зависимости от операционной системы существуют способы увеличить это ограничение файлов на процесс. Тем не менее, вы должны спросить себя, действительно ли вам это нужно. Есть только несколько законных вариантов использования для выбора этого решения.
Один допустимый сценарий для серверов. Серверы работают с сокетами, которые во многом похожи на файлы. Операционная система отслеживает сокеты в таблице файлов, используя дескрипторы файлов. Серверу может потребоваться открыть много сокетов для каждого клиента, к которому они подключаются. Кроме того, сервер может обмениваться данными с несколькими клиентами. Эта ситуация может привести к тому, что потребуются многие тысячи файловых дескрипторов.
Как ни странно, несмотря на то, что некоторые приложения могут требовать увеличения лимита операционной системы для открытых файлов, обычно именно эти приложения должны быть особенно внимательны при закрытии файлов!
Возможно, вы думаете, что вам не грозит непосредственная опасность достижения предела. Тем не менее, читайте дальше, потому что в следующем разделе вы более подробно рассмотрите некоторые последствия случайного превышения этого предела.
Каковы реальные последствия превышения лимита файлов?
Если вы открываете файлы и никогда не закрываете их в Python, вы можете не заметить никакой разницы, особенно если вы работаете над однофайловыми сценариями или небольшими проектами. Однако по мере того, как проекты, над которыми вы работаете, усложняются, вы будете все чаще сталкиваться с проблемными ситуациями.
Представьте, что вы работаете в большой команде над огромной кодовой базой. Затем в один прекрасный день вы достигнете предела для открытых файлов. Фишка в том, что сообщение об ошибке для лимита не скажет вам , где проблема. Это будет универсальный OSError
, которую вы видели ранее, которая сообщает вам только Слишком много открытых файлов
.
В вашей кодовой базе могут быть тысячи мест, где вы открываете файлы. Представьте себе поиск мест, где код неправильно обрабатывает файлы. Представьте, что код передает файловые объекты между функциями, и вы не можете сразу сказать, закрыт какой-либо данный файловый объект в конечном итоге или нет. Это не веселое время.
Если вам интересно, есть способы изучить дескрипторы открытых файлов вашей системы. Разверните следующий блок для изучения:
- Окна
- Linux + macOS
Установка процесса хакера:
PS> выборочная установка процесса хакера
Откройте приложение и нажмите кнопку Найти дескрипторы или библиотеки DLL . Установите флажок regex и введите .*
, чтобы увидеть все дескрипторы файлов с сопутствующей информацией.
Официальная версия Microsoft process hacker входит в состав утилит Sysinternals, а именно Process Monitor и Process Explorer.
Возможно, вам потребуется установить lsof
, утилиту Linux для l i s t o pen f файлов. С помощью этой утилиты вы можете получить информацию и подсчитать количество открытых файлов:
$ lsof | голова $ лсоф | туалет -л
Команда lsof
печатает новую строку для каждого открытого файла с основной информацией об этом файле. Введя его в команду head
, вы увидите начало вывода, включая имена столбцов.
Вывод lsof
может быть передан в команду wc
или подсчет слов. Переключатель -l
означает, что будут учитываться только новые строки. Вероятно, это число будет исчисляться сотнями тысяч.
Вы можете направить вывод lsof
в grep
, чтобы найти строки, содержащие строку типа python
. Вы также можете передать идентификатор процесса, который может быть полезен, если вы хотите найти файловые дескрипторы:
$ lsof | питон
Эта команда отфильтрует все строки, которые не содержат термин после grep
, в данном случае python
.
Если вас интересует теоретический предел для файлов в вашей системе, вы можете изучить его в системах на базе UNIX, изучив содержимое специального файла:
$ cat /proc/sys/fs/file-max
Число сильно зависит от платформы, но, скорее всего, оно велико. Система почти наверняка исчерпает другие ресурсы, прежде чем достигнет этого предела.
Вы можете задаться вопросом почему операционная система ограничивает файлы. Предположительно, он может обрабатывать гораздо больше файловых дескрипторов, чем показывает, верно? В следующем разделе вы узнаете, почему операционная система заботится об этом.
Почему операционная система ограничивает число дескрипторов файлов?
Фактические пределы количества файлов, которые операционная система может держать открытыми одновременно, огромны. Вы говорите о миллионах файлов. Но на самом деле достижение этого предела и присвоение ему фиксированного числа не является четким. Как правило, система исчерпает другие ресурсы раньше, чем закончатся дескрипторы файлов.
Предел консервативен с точки зрения операционной системы, но вполне достаточен с точки зрения большинства программ. С точки зрения операционной системы, любой процесс, который достигает предела, вероятно, приводит к утечке файловых дескрипторов вместе с другими ресурсами.
Утечка ресурсов может быть вызвана плохой практикой программирования или попыткой вредоносной программы атаковать систему. Вот почему операционная система накладывает ограничения — чтобы уберечь вас от других и от самого себя!
Плюс, для большинства приложений нет смысла открывать столько файлов. На одном жестком диске одновременно может выполняться не более одной операции чтения или записи, поэтому если вы работаете только с файлами, процесс не ускорится.
Итак, вы знаете, что открывать много файлов проблематично, но есть и другие недостатки, связанные с тем, что вы не закрываете файлы в Python, даже если вы открываете только несколько.
Удалить рекламу
Что произойдет, если вы не закроете файл и произойдет сбой Python?
В этом разделе вы поэкспериментируете с моделированием сбоя и увидите, как это влияет на открытые файлы. Вы можете использовать специальную функцию в модуле os
, которая завершится без выполнения какой-либо очистки, которую обычно делает Python, но сначала вы увидите, как все обычно очищается.
Выполнение операций записи для каждой команды может быть дорогостоящим. По этой причине по умолчанию Python использует буфер, который собирает операции записи. Когда буфер заполняется или когда файл явно закрывается, буфер сбрасывается, и операция записи завершается.
Python усердно работает, чтобы убрать за собой. В большинстве случаев он сам проактивно очищает и закрывает файлы:
# write_hello.py файл = открыть ("hello.txt", режим = "w") file.write("Привет, мир!")
При выполнении этого кода операционная система создает файл. Операционная система также записывает содержимое, даже если вы никогда не очищаете и не закрываете файл в коде. Об этой очистке и закрытии заботится подпрограмма очистки, которую Python выполнит в конце выполнения.
Однако иногда выходы не так контролируются, и сбой может привести к обходу этой очистки:
# сбой_hello. py импорт ОС файл = открыть ("crash.txt", режим = "w") file.write("Привет, мир!") os._exit(1)
После запуска фрагмента выше вы можете использовать cat
для проверки содержимого только что созданного файла:
$ кошка краш.txt $ # Нет вывода!
Вы увидите, что несмотря на то, что операционная система создала файл, в нем нет содержимого. Отсутствие выхода, потому что os._exit()
обходит обычную процедуру выхода Python, имитируя сбой. Тем не менее, даже этот тип симуляции относительно контролируем, поскольку предполагает, что произошел сбой Python, а не вашей операционной системы.
За кулисами, как только Python завершится, операционная система также выполнит собственную очистку, закрыв все файловые дескрипторы, открытые процессом. Сбои могут возникать на многих уровнях и мешать очистке операционной системы, оставляя дескрипторы файлов «висящими».
В Windows, например, висячие дескрипторы файлов могут быть проблематичными, поскольку любой процесс, который открывает файл, также блокирует его. Другой процесс не может открыть этот файл, пока он не будет закрыт. Пользователи Windows могут быть знакомы с мошенническими процессами, которые не позволяют вам открывать или удалять файлы.
Что может быть хуже блокировки файлов? Утечка файловых дескрипторов может представлять угрозу безопасности, поскольку разрешения, связанные с файлами, иногда смешиваются.
Примечание : Наиболее распространенная реализация Python, CPython, идет дальше в очистке дескрипторов оборванных файлов, чем вы думаете. Он использует подсчет ссылок для сборки мусора, поэтому файлы закрываются, когда на них больше не ссылаются. Тем не менее, другие реализации, такие как PyPy, используют другие стратегии, которые могут быть не такими агрессивными при очистке неиспользуемых файловых дескрипторов.
Тот факт, что некоторые реализации могут выполнять очистку не так эффективно, как CPython, является еще одним аргументом в пользу постоянного использования менеджера контекста!
Утечка файловых дескрипторов и потеря содержимого в буфере — это уже достаточно плохо, но сбой, прерывающий операцию с файлом, также может привести к повреждению файла. Это значительно увеличивает вероятность потери данных. Опять же, это маловероятные сценарии, но они могут быть дорогостоящими.
Вы никогда не сможете полностью оградить себя от сбоя, но вы можете уменьшить воздействие, используя контекстный менеджер. Синтаксис менеджера контекста, естественно, приведет вас к коду, который будет держать файл открытым только до тех пор, пока он необходим.
Заключение
Вы узнали почему важно закрывать файлы в Python . Поскольку файлы — это ограниченные ресурсы, которыми управляет операционная система, убедитесь, что файлы закрыты после использования, чтобы защитить от трудно отлаживаемых проблем, таких как исчерпание файловых дескрипторов или повреждение данных. Лучшая защита — всегда открывать файлы с помощью контекстного менеджера.
Копаясь глубже, вы видели, что происходит, когда вы открываете слишком много файлов, и вы спровоцировали сбой, который приводит к пропаже содержимого файла. Дополнительные сведения об открытии файлов см.