在Python中显式关闭文件的方法

11 投票
2 回答
15641 浏览
提问于 2025-04-18 16:21

请看下面的代码:

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

这段代码看起来是按照所有Python的规则写的;用完文件后也有关闭的操作。看起来是这样。但实际上,它似乎是建议系统去关闭文件,而不是在代码里明确关闭,因为我在资源监视器上看到有很多打开的文件。这给我带来了很多问题,因为我的脚本使用了很多文件,经过一段时间后,我收到了“打开的文件太多”的错误,尽管我在源代码里已经“关闭”了它。

有没有什么方法可以在Python中明确关闭文件?或者我怎么能检查文件是否真的被关闭了呢?

更新:我刚刚用另一个监控工具——Sysinternals的Handle试了一下,它显示的都是正确的,我相信它。所以,这可能是资源监视器本身的问题。

下面是显示打开文件的截图:

运行脚本的资源监视器

2 个回答

-3

你可以通过调用 qq.close() 来明确地关闭文件。另外,Python 在处理文件时,并不会在用完后立刻关闭它,这和它处理垃圾回收的方式类似。你可能需要了解一下如何让 Python 释放所有未使用的文件描述符。如果它的处理方式和未使用的变量相似的话,Python 会告诉操作系统它仍在使用这些文件描述符,无论这些文件描述符当前是否被你的程序使用。

11

你的代码

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环境版本有个bug,导致fclose()没有被调用,可能是某种原因造成的。

不过你可以尝试一下像

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

这样的代码,它直接进行系统调用。

撰写回答