5

在测试以下代码时,我对此有疑问:

1、

def file_close_test():
    f = open('/tmp/test', 'w+')

if __name__ == '__main__':
    file_close_test()
    # wait to see whether file closed.
    import time
    time.sleep(30)

2、

def file_close_on_exc_test():
    f = open('/tmp/test', 'w+')
    raise Exception()

def exception_wrapper():
    try:
        file_close_on_exc_test()
    except:
        pass
    # wait to see whether file closed.
    import time
    time.sleep(10)

if __name__ == '__main__':
    exception_wrapper()
    import time
    time.sleep(30)
  1. 文件对象在file_close_test退出时关闭,因为没有引用它。
  2. 引发异常后,文件对象没有关闭。所以我认为相关的堆栈数据没有释放。
  3. exception_wrapper退出后,文件自动关闭。

你能为我解释一下吗?谢谢。

4

1 回答 1

3

异常包括一个回溯对象,该对象可用于访问抛出异常时活动的任何堆栈帧中的所有局部变量。这意味着您仍然可以访问该文件,直到清除异常上下文。

即使在sleep()结束之后,exception_wrapper您也可以使用sys.exc_info以下方式获取打开的文件:

tb = sys.exc_info()[2]
print tb.tb_next.tb_frame.f_locals['f']

当然,所有这些都特定于您正在使用的特定 Python 实现。其他实现可能根本不会隐式关闭文件,直到它们被垃圾收集。

底线是你永远不应该依赖 Python 的引用计数或垃圾收集来清理打开的文件等资源,总是明确地这样做。

于 2012-05-29T11:12:27.600 回答