简体   繁体   English

为什么 Python 在调用 file.close() 后不释放文件句柄?

[英]Why doesn't Python release file handles after calling file.close()?

I am on windows with Python 2.5.我在使用 Python 2.5 的 Windows 上。 I have an open file for writing.我有一个用于写作的打开文件。 I write some data.我写一些数据。 Call file close.调用文件关闭。 When I try to delete the file from the folder using Windows Explorer, it errors, saying that a process still holds a handle to the file.当我尝试使用 Windows 资源管理器从文件夹中删除文件时,它出错,说一个进程仍然持有该文件的句柄。

If I shutdown python, and try again, it succeeds.如果我关闭 python,然后再试一次,它会成功。

It does close them.它确实关闭了它们。 Are you sure f.close() is getting called?你确定 f.close() 被调用了吗? I just tested the same scenario and windows deletes the file for me.我刚刚测试了相同的场景,Windows 为我删除了该文件。

Are you handling any exceptions around the file object?您是否在处理文件对象周围的任何异常? If so, make sure the error handling looks something like this:如果是这样,请确保错误处理如下所示:

f = open("hello.txt")
try:
    for line in f:
        print line
finally:
    f.close()

In considering why you should do this, consider the following lines of code:在考虑为什么要这样做时,请考虑以下代码行:

f = open('hello.txt')
try:
    perform_an_operation_that_causes_f_to_raise_an_exception()
    f.close()
except IOError:
    pass

As you can see, f.close will never be called in the above code.如您所见,在上面的代码中永远不会调用 f.close。 The problem is that the above code will also cause f to not get garbage collected.问题是上面的代码也会导致 f 没有被垃圾回收。 The reason is that f will still be referenced in sys.traceback, in which case the only solution is to manually call close on f in a finally block or set sys.traceback to None (and I strongly recommend the former).原因是 f 仍将在 sys.traceback 中引用,在这种情况下,唯一的解决方案是在 finally 块中手动调用 f 上的 close 或将 sys.traceback 设置为 None(我强烈推荐前者)。

Explained in the tutorial:教程中解释:

with open('/tmp/workfile', 'r') as f:
    read_data = f.read()

It works when you writing or pickling/unpickling, too它在您写作或酸洗/解酸时也有效

It's not really necessary that try finally block: Java way of doing things, not Python try finally 块并不是真的有必要:Java 的做事方式,而不是 Python

I was looking for this, because the same thing happened to me.我正在寻找这个,因为同样的事情发生在我身上。 The question didn't help me, but I think I figured out what happened.这个问题对我没有帮助,但我想我知道发生了什么。

In the original version of the script I wrote, I neglected to add in a 'finally' clause to the file in case of an exception.在我编写的脚本的原始版本中,我忽略了在文件中添加“finally”子句以防万一。

I was testing the script from the interactive prompt and got an exception while the file was open.我正在从交互式提示测试脚本,并在文件打开时遇到异常。 What I didn't realize was that the file object wasn't immediately garbage-collected.我没有意识到文件对象没有立即被垃圾收集。 After that, when I ran the script (still from the same interactive session), even though the new file objects were being closed, the first one still hadn't been, and so the file handle was still in use, from the perspective of the operating system.在那之后,当我运行脚本时(仍然来自同一个交互式会话),即使新的文件对象正在关闭,第一个仍然没有关闭,因此文件句柄仍在使用中,从操作系统。

Once I closed the interactive prompt, the problem went away, at which I remembered that exception occurring while the file was open and realized what had been going on.一旦我关闭交互式提示,问题就消失了,我记得在打开文件时发生了异常并意识到发生了什么。 (Moral: Don't try to program on insufficient sleep. : ) ) (道德:不要试图在睡眠不足的情况下编程。:))

Naturally, I have no idea if this is what happened in the case of the original poster, and even if the original poster is still around, they may not remember the specific circumstances, but the symptoms are similar, so I thought I'd add this as something to check for, for anyone caught in the same situation and looking for an answer.当然,我不知道原发帖人的情况是不是这样,即使原发帖人还在,他们可能不记得具体情况,但症状相似,所以我想我会补充对于任何陷入相同情况并寻找答案的人来说,这是要检查的东西。

I did it using intermediate file:我使用中间文件做到了:

import os

f = open("report.tmp","w")
f.write("{}".format("Hello"))
f.close()
os.system("move report.tmp report.html") #this line is for Windows users

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM