如果Python不在本地范围内,它会关闭fd吗?

时间:2013-10-12 09:21:20

标签: python file file-descriptor

我发现Python会自动关闭我的文件描述符。运行以下代码并使用 lsof 查找打开的文件。在函数openAndSleep中睡眠时,我发现文件“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 __ 方法。这看起来很奇怪,有人知道吗?

2 个答案:

答案 0 :(得分:3)

是的,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 slotfile_dealloc() function关闭文件对象。

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

答案 1 :(得分:1)

简而言之:是的。

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

文件对象是Pythonic对象,与Python中的任何其他对象相同,它们也由垃圾收集器管理。离开函数作用域后,垃圾收集器会发现没有人使用该文件(使用引用计数器)并处理该对象 - 这也意味着关闭它。

您可以采取的措施是通过使用返回文件描述符(int)而不是Python文件对象的os.open来打开文件而不使用Python文件对象。垃圾收集器不会丢弃文件描述符,因为它不是Python对象而是操作系统对象,因此您的代码将起作用。 不过,你应该小心关闭(os.close)fd,否则你会泄漏资源,迟早你的程序会崩溃(一个进程只能存储1024个文件描述符,然后就不能再打开文件了) !

其他信息:

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