39

一些代码:

import cStringIO

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

文档说:

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

4 回答 4

19

一般还是调用close()或者使用with语句比较好,因为在特殊情况下可能会出现一些意想不到的行为。例如,expat-IncrementalParser似乎期望一个文件被关闭,或者它不会返回已解析 xml 的最后一点,直到在某些极少数情况下发生超时。

但是对于with为您处理关闭的 -statement,您必须使用 -Modules 中的StringIOio,如 Ivc 的评论中所述。

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

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

于 2012-03-15T11:56:41.283 回答
17

从来源:

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

所以StringIO.close只是释放内存缓冲区删除对StringIO.buf和的引用StringIO.pos。但是如果self是垃圾回收,它的属性也会被垃圾回收,效果和StringIO.close.

于 2013-08-23T09:01:37.987 回答
9

StringIO.close()只是为接受类似文件并最终尝试关闭它们的例程提供便利。没有必要自己这样做。

于 2012-03-15T11:50:07.503 回答
2

我最后用一个try块来处理它。

import cStringIO

def f():
    buffer = cStringIO.StringIO()
    try:
        buffer.write('something')
        return buffer.getvalue()
    finally:
        buffer.close()
于 2014-04-08T17:21:51.007 回答