【问题标题】:Explicit way to close file in Python在 Python 中关闭文件的显式方法
【发布时间】:2014-08-07 07:05:33
【问题描述】:

请看以下代码:

for i in xrange(1,5000):
    with open(r'test\test%s.txt' % i, 'w') as qq:
        qq.write('aa'*3000)

好像是按照所有Python规则写的;文件在使用后关闭。好像。但实际上它似乎建议(!)系统关闭文件,而不是明确关闭它,因为当我查看资源监视器时,它显示了很多打开的文件。它给我带来了很多问题,因为在我的脚本中我使用了很多文件,并且在很长一段时间后,尽管从源代码中“关闭”了它,但我得到了“打开的文件太多”错误。

有没有办法在 Python 中显式关闭文件?或者如何检查文件是否真的(!)关闭?

更新:我刚刚尝试使用另一个监控工具 - 来自 Sysinternals 的句柄,它显示一切正确,我相信它。所以,这可能是资源监视器本身的问题。

显示打开文件的屏幕截图:

【问题讨论】:

  • 我无法重现此内容。请您提供一个显示此行为的 SSCCE (sscce.org)(您现在显示的代码与屏幕截图不一致),并让我们知道您的确切 Python 版本和操作系统的详细信息。
  • 你想说这是唯一的方法吗?我的意思是,我不想让所有这些文件保持打开状态,我只需要一个文件及时但 Python 在我的请求后没有关闭它,似乎它们仍然保持打开状态。我知道我可以增加打开文件数量的操作系统限制,但我认为这不是一个好的解决方案。
  • Python 2.7,Windows 7 64 位操作系统。唯一的区别是文件名。
  • 运行上述测试脚本是否会出现“打开的文件过多”错误?
  • 我无法重现此问题。 Windows 7 64 位,Python 2.7.5 - 使用您的确切代码。我确实注意到您正在运行同一程序的多个副本(在后台屏幕截图中);这将导致文件处理程序出现竞争条件,并且可能是造成这种情况的原因。

标签: python file


【解决方案1】:

你的代码

for i in xrange(1, 5000):
    with open(r'test\test%s.txt' % i, 'w') as qq:
        qq.write('aa' * 3000)

在语义上完全等价于

for i in xrange(1, 5000):
    qq = open(r'test\test%s.txt' % i, 'w')
    try:
        qq.write('aa' * 3000)
    finally:
        qq.close()

将with 与文件一起使用是一种确保在离开with 块后立即关闭文件的方法。

所以你的问题一定出在其他地方。

可能正在使用的 Python 环境版本存在一个错误,即由于某种原因没有调用 fclose()。

但你可以尝试类似的东西

try:
    qq.write('aa' * 3000)
finally:
    # qq.close()
    os.close(qq.fileno())

系统直接调用。

【讨论】:

  • 我知道,但问题仍然存在。我调用“关闭”但实际上文件并未关闭(处理程序仍在系统中,这就是资源监视器显示的内容)
  • @TheGodfather 我已添加到我的答案中,以便对您有所帮助。
  • 在 Python 级别,它是关闭的。菲尼托。如果它仍然在系统级别打开,问题可能出在:1)您正在使用的 Python 实现,2)操作系统及其内核,3)您用于监视打开的文件的工具。
【解决方案2】:

您应该能够通过调用 qq.close() 显式关闭文件。此外,python 在处理完文件后不会立即关闭文件,类似于它处理垃圾收集的方式。您可能需要研究如何让 python 释放其所有未使用的文件描述符。如果它类似于它处理未使用变量的方式,那么它将告诉操作系统它仍在使用它们,无论它们当前是否被您的程序使用。

【讨论】:

  • for i in xrange(1,5000): try: qq = open(r'test\scr%s.png' % i, 'w') qq.write('aa'*3000 ) 最后: qq.close() 使用此代码,问题仍然存在。 >此外,python 在完成文件后不会立即关闭文件,这正是我所要求的。如何在使用后立即显式关闭文件。
  • 大卫,你看到了with 声明,不是吗?你写的关于释放文件描述符的内容只保留没有 with 的东西或明确关闭。
  • @glglgl 是的,我做到了。抱歉,这里来晚了。我确实认为它类似于它处理垃圾收集的方式。我最近遇到了一个问题,我正在制作的 python 程序内存不足。事实证明,当我完成一个变量并删除它时,python 实际上并没有释放该变量。事实证明,它只在每创建 700 个对象时运行一次垃圾收集。这意味着我必须强制它运行垃圾收集。这可能是一个类似的问题,因为您没有明确关闭文件。
  • @David with确实明确关闭文件!
  • @glglgl 是的,我相信 'with' 明确调用 f.close() 但实际上它似乎没有关闭文件处理程序。
猜你喜欢
  • 2021-12-19
  • 2012-05-15
  • 2011-07-08
  • 2011-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-15
相关资源
最近更新 更多