我必须做StringIO.close()吗?

时间:2012-03-15 11:40:58

标签: python stringio

一些代码:

import cStringIO

def f():
    buffer = cStringIO.StringIO()
    buffer.write('something')
    return buffer.getvalue()

documentation说:

  

StringIO.close():释放内存缓冲区。试图做进一步   使用已关闭的StringIO对象的操作将引发ValueError。

我必须做buffer.close(),否则当缓冲区超出范围并被垃圾收集时会自动发生?

更新

我做了一个测试:

import StringIO, weakref

def handler(ref):
    print 'Buffer died!'

def f():
    buffer = StringIO.StringIO()
    ref = weakref.ref(buffer, handler)
    buffer.write('something')
    return buffer.getvalue()

print 'before f()'
f()
print 'after f()'

结果:

vic@wic:~/projects$ python test.py 
before f()
Buffer died!
after f()
vic@wic:~/projects$

4 个答案:

答案 0 :(得分:14)

通常,调用close()或使用with语句仍然更好,因为在特殊情况下可能会出现一些意外行为。例如,expat - IncrementalParser似乎期望文件被关闭,或者它将不会返回解析的xml的最后一个tidbit,直到在某些罕见的情况下发生超时。

但对于处理结束的with - 语句,您必须使用StringIO - 模块中的io类,如Ivc的注释中所述。

这是我们通过手动关闭StringIO解决的一些遗留sax-parser脚本中的一个主要问题。

“超出范围”的关闭不起作用。它只是等待超时限制。

答案 1 :(得分:11)

来自消息来源:

class StringIO:
    ...
    def close(self):
        """Free the memory buffer.
        """
        if not self.closed:
            self.closed = True
            del self.buf, self.pos

所以StringIO.close只是释放内存缓冲区,删除对StringIO.bufStringIO.pos的引用。但如果self被垃圾收集,其属性也将被垃圾收集,效果与StringIO.close相同。

答案 2 :(得分:8)

StringIO.close()仅仅是一种方便的例程,它采用类似文件并最终尝试关闭它们。没有必要自己这样做。

答案 3 :(得分:3)

我使用try块来处理它。

import cStringIO

def f():
    buffer = cStringIO.StringIO()
    try:
        buffer.write('something')
        return buffer.getvalue()
    finally:
        buffer.close()