【问题标题】:Close all open files in ipython关闭 ipython 中所有打开的文件
【发布时间】:2012-02-17 21:49:42
【问题描述】:

有时在使用 ipython 时,您可能会在以写入模式打开文件的函数中遇到异常。这意味着下次运行该函数时会出现值错误,

ValueError:文件“文件名”已打开。请先关闭它,然后再以写入模式重新打开。

但是,由于函数出错,文件句柄(在函数内部创建)丢失了,因此无法关闭。唯一的办法似乎是关闭 ipython 会话,此时您会收到消息:

关闭剩余打开的文件:文件名...完成

有没有办法指示 ipython 在不退出会话的情况下关闭文件?

【问题讨论】:

  • 在处理文件时,您应该尝试始终使用with 语句,例如,使用with open("x.txt") as fh: <do something with data>。这样可以确保如果出现问题,文件一定会被关闭。
  • @Chris 您应该将其发布为答案,因为这是唯一有效且简单的解决方案
  • @JBernardo 感谢您的建议 - 完成。

标签: python ipython filehandle


【解决方案1】:

在处理文件时,您应该尝试始终使用with 语句。例如,使用类似

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

这确保了如果在with 块的执行过程中出现问题,并且引发了异常,则保证文件被关闭。有关这方面的更多信息,请参阅with documentation

编辑:根据 cmets 中的讨论,似乎 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 块包含应该在任何tryexceptelse 块之后运行的代码,即使发生异常也是如此。来自documentation

如果finally 存在,它指定一个“清理”处理程序。执行try 子句,包括任何exceptelse 子句。如果任一子句发生异常且未处理,则暂时保存该异常。执行finally 子句。如果有一个保存的异常,它会在finally 子句的末尾重新引发。如果finally 子句引发另一个异常或执行return 或break 语句,则保存的异常将丢失。在执行finally 子句期间,程序无法获得异常信息。

【讨论】:

  • 好的,但我使用这种方法遇到的问题是我正在循环打开几个文件,例如for fname in fname_list: file_list.append(open(fname)) 因为稍后我必须对列表进行操作。如果我使用 with ... 方法,那么所有文件都在循环中关闭 - 即我不能打开多个文件。
  • 您需要同时打开多个文件吗?如果没有,那么只需使用for fname in fname_list: with open(fname) as fh: <do something with the file stream fh>。您最初的部分问题是您将文件打开,然后无法关闭它们,我们出了点问题 - 一次打开一个更安全。
  • 我需要打开多个文件,因为我在 HDF5 中有多组数据并且我正在使用 pytables 来访问它们。要使用 pytables,文件需要保持打开状态
  • 我认为你没有理解我的意思。是的,文件需要在工作时保持打开状态,是的,您需要处理多个文件,但是您是否需要一次处理多个文件?你不能打开一个文件,提取你需要的数据(绘制它,无论如何),关闭文件然后打开下一个文件吗?
  • 不,我没有错过重点。 pytables 允许您动态访问磁盘文件,因此您不必将所有内容加载到内存中。我正在对存储在不同文件中的部分矩阵进行数学运算。这些是无法存储在内存中的非常大的矩阵。我能看到的唯一解决方法是将所有内容存储在一个巨大的文件中(这可能是 ~1Tb),但我不确定如果我这样做会遇到什么问题
【解决方案2】:

一些想法:

  • 在处理文件时始终使用finally(或with 块),以便正确关闭它们。
  • 您可以使用os.close(n) 盲目地关闭非标准文件描述符,其中n 是一个大于2 的数字(这是特定于unix 的,因此您可能想查看/proc/ipython_pid/fd/ 以查看进程打开了哪些描述符,所以远)。
  • 您可以检查捕获的本地堆栈帧,看看是否可以找到对任性文件的引用并关闭它...看看sys.last_traceback

【讨论】:

    猜你喜欢
    • 2010-11-21
    • 2021-03-02
    • 1970-01-01
    • 2014-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-26
    • 1970-01-01
    相关资源
    最近更新 更多