Закрыть все открытые файлы в ipython

Иногда при использовании ipython вы можете получить исключение в функции, которая открыла файл в режиме записи. Это означает, что при следующем запуске функции вы получите ошибку значения,

ValueError: файл 'filename' уже открыт. Закройте его перед повторным открытием в режиме записи.

Однако, поскольку функция отключена, дескриптор файла (который был создан внутри функции) потерян, поэтому он не может быть закрыт. Единственный способ закрыть его, похоже, закрыть сессию ipython, после чего вы получите сообщение:

Закрытие остальных открытых файлов: filename... done

Есть ли способ проинструктировать ipython для закрытия файлов без выхода из сеанса?

Ответ 1

При работе с файлами следует всегда использовать инструкцию with. Например, используйте что-то вроде

with open("x.txt") as fh:
    ...do something with the file handle fh

Это гарантирует, что если во время выполнения блока with что-то пойдет не так, и возникнет исключение, файл будет закрыт. Дополнительную информацию об этом см. В с документацией.

Изменить. После обсуждения в комментариях кажется, что OP должен одновременно открывать несколько файлов и использовать данные из нескольких файлов одновременно. Очевидно, что наличие множества вложенных операторов with, по одному для каждого открытого файла, не является опцией и противоречит идеалу, что "квартира лучше, чем вложенная".

Один вариант - обернуть вычисление в блок try/finally. Например

file_handles = []
try:
    for file in file_list:
        file_handles.append(open(file))

    # Do some calculations with open files

finally:
    for fh in file_handles:
        fh.close()

Блок finally содержит код, который должен запускаться после любого блока try, except или else, даже если произошло исключение. Из документации:

Если присутствует finally, он указывает обработчик "очистка". Выполняется предложение try, включая любые предложения except и else. Если исключение возникает в любом из предложений и не обрабатывается, исключение временно сохраняется. Выполняется предложение finally. Если есть сохраненное исключение, оно будет повторно поднято в конце предложения finally. Если предложение finally вызывает другое исключение или выполняет оператор return или break, сохраненное исключение теряется. Информация об исключении недоступна программе во время выполнения предложения finally.

Ответ 2

Несколько идей:

  • всегда используйте finally (или блок with) при работе с файлами, поэтому они правильно закрыты.
  • вы можете вслепую закрыть нестандартные дескрипторы файлов, используя os.close(n), где n - число больше 2 (это специфично для unix, поэтому вы можете просмотреть /proc/ipython_pid/fd/, чтобы увидеть, какие дескрипторы процесса открылись, далеко).
  • вы можете проверить локализованные локаторы кадров стека, чтобы узнать, можете ли вы найти ссылку на своенравный файл и закрыть его... взгляните на sys.last_traceback