2

我发现 Python 会自动关闭我的文件描述符。运行以下代码并使用lsof查找打开的文件。当 sleep in functionopenAndSleep时,我发现文件“fff”被进程持有。但是当它用完函数时,文件“fff”不再保存。

import time

def openAndSleep():
    f = open("fff", 'w')
    print "opened, sleep 10 sec"
    time.sleep(10)
    print "sleep finish"

openAndSleep()
print "in main...."
time.sleep(10000)

我检查类文件,它没有__del__方法。好像很奇怪,有人知道吗?

4

2 回答 2

5

是的,CPython 会。

当文件对象的引用计数下降到 0 时,文件对象会自动关闭。正在清理的本地范围意味着 refcount 下降,如果本地范围是唯一的引用,则文件对象的 refcount 下降到 0 并关闭。

但是,最好在with语句中使用文件对象作为上下文管理器,并以这种方式自动关闭它;不要指望CPython的特定垃圾处理实现:

def openAndSleep():
    with open("fff", 'w') as f:
        print "opened, sleep 10 sec"
        time.sleep(10)
        print "sleep finish"

请注意,这__del__是自定义 Python 类的钩子;文件对象在 C 中实现并填充tp_dealloc插槽。该file_dealloc()函数关闭文件对象。

如果您想保持文件对象打开更长时间,请确保仍然存在对它的引用。也在其他地方存储对它的引用。例如,从函数中返回它并存储返回值,或者将其设为全局等。

于 2013-10-12T09:22:38.530 回答
2

简而言之:是的。

Python 通过实现垃圾收集机制使用户无需管理他的内存。这基本上意味着 Python 中的每个对象将在没有人使用时自动释放和删除,以释放内存和资源,以便稍后在程序中再次使用它们。

文件对象是 Pythonic 对象,与 Python 中的任何其他对象相同,它们也由垃圾收集器管理。一旦您离开函数范围,垃圾收集器就会看到没有人使用该文件(使用引用计数器)并处置该对象 - 这也意味着关闭它。

为了避免这种情况,您可以做的是在不使用 Python 文件对象的情况下打开文件,方法是使用os.open它返回文件描述符 (int) 而不是 Python 文件对象。然后垃圾收集器不会丢弃文件描述符,因为它不是 Python 对象而是操作系统对象,因此您的代码将起作用。但是,您应该小心os.close稍后关闭()fd,否则您会泄漏资源并且迟早您的程序会崩溃(一个进程只能存储 1024 个文件描述符,然后就不能再打开文件了)!

附加信息:

http://www.digi.com/wiki/developer/index.php/Python_Garbage_Collection

于 2013-10-12T09:37:02.997 回答