Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我必须执行StringIO.close()吗?_Python_Stringio - Fatal编程技术网

Python 我必须执行StringIO.close()吗?

Python 我必须执行StringIO.close()吗?,python,stringio,Python,Stringio,一些代码: import cStringIO def f(): buffer = cStringIO.StringIO() buffer.write('something') return buffer.getvalue() 报告说: StringIO.close():释放内存缓冲区。试图做得更进一步 使用关闭的StringIO对象的操作将引发ValueError 我必须执行buffer.close(),还是在缓冲区超出范围并被垃圾回收时自动执行 更新: 我做了一个测

一些代码:

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$

StringIO.close()
只是为那些获取类似文件并最终尝试关闭它们的例程提供了方便。您自己不需要这样做。

一般来说,最好调用
close()
或使用
with
语句,因为在特殊情况下可能会出现一些意外行为。例如,expat-
IncrementalParser
似乎希望关闭一个文件,或者在某些罕见的情况下,直到超时发生,它才会返回解析的xml的最后一丁点

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

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

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

来源:

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
相同。我使用
try
块来处理它

import cStringIO

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

这不是一种方便,而是一种必要。如果没有它,像对象一样关闭文件的代码将被破坏。@Maxim:这是该代码的必要条件。这对客户端来说是一种方便。请注意Py2中的StringIO和cStringIO没有实现上下文管理器协议-因此,要在
with
语句中使用它,您需要使用contextlib.closing(StringIO())作为缓冲区:。另一方面,Py3的
io.StringIO
可以直接在
with
语句中使用。
io.StringIO
确实实现了上下文管理器协议,但不是之前的2.6版本。请看:`啊,我还没有意识到
io
模块早就存在了。谢谢你的指点。但是,OP中使用的
StringIO.StringIO
cStringIO.StringIO
模块仍然没有。事实上,我有点惊讶于它们在2.6/2.7中没有被标记为不推荐使用,而且在2.7文档中甚至没有通常的注释说“这些在3.x中不再存在”。你是对的,坦率地说,我没有真正注意到这个事实,OP没有使用io模块!谢谢你指出这一点!;-)为什么不打印f(),而不是只打印一个裸f()?或者,从
contextlib.closing
使用带有closing()的