在Python 3中重新打开一个已关闭的stringIO对象

Pra*_*van 5 file-io python-3.x

所以,我创建一个StringIO对象来将我的字符串视为一个文件:

>>> a = 'Me, you and them\n'
>>> import io
>>> f = io.StringIO(a)
>>> f.read(1)
'M'
Run Code Online (Sandbox Code Playgroud)

然后我继续关闭'文件':

>>> f.close()
>>> f.closed
True
Run Code Online (Sandbox Code Playgroud)

现在,当我再次尝试打开'文件'时,Python不允许我这样做:

>>> p = open(f)
Traceback (most recent call last):
  File "<pyshell#166>", line 1, in <module>
    p = open(f)
TypeError: invalid file: <_io.StringIO object at 0x0325D4E0>
Run Code Online (Sandbox Code Playgroud)

有没有办法'重新打开'一个封闭的StringIO对象?或者是否应该使用io.StringIO()方法再次声明?

谢谢!

rap*_*ner 8

不,没有办法重新打开io.StringIO对象。相反,只需使用 . 创建一个新对象即可io.StringIO()

调用close()对象io.StringIO会丢弃“文件内容”数据,因此重新打开无论如何都无法访问该数据。

如果您需要数据,请getvalue()在关闭前致电。

另请参阅此处文档StringIO

调用 close() 方法时,文本缓冲区将被丢弃。

和这里:

getvalue()

返回包含缓冲区全部内容的 str。


use*_*109 6

我有一个不错的 hack,我目前正在使用它进行测试(因为我的代码可以进行 I/O 操作,并且给它 StringIO 是一个不错的选择)。

如果这个问题是一次性的:

st = StringIO()
close = st.close
st.close = lambda: None
f(st)  # Some function which can make I/O changes and finally close st
st.getvalue()  # This is available now
close() # If you don't want to store the close function you can also:
StringIO.close(st)
Run Code Online (Sandbox Code Playgroud)

如果这是重复发生的事情,您还可以定义上下文管理器:

@contextlib.contextmanager
def uncloseable(fd):
    """
    Context manager which turns the fd's close operation to no-op for the duration of the context.
    """
    close = fd.close
    fd.close = lambda: None
    yield fd
    fd.close = close
Run Code Online (Sandbox Code Playgroud)

可以通过以下方式使用:

st = StringIO()
with uncloseable(st):
    f(st) 
# Now st is still open!!!
Run Code Online (Sandbox Code Playgroud)

我希望这可以帮助您解决问题,如果没有,我希望您能找到您正在寻找的解决方案。注意:对于其他类似文件的对象,这应该完全相同。


小智 4

内置的open()创建一个文件对象(即流),但在您的示例中, f 已经是一个流。这就是你得到 TypeError: invalid file 的原因

执行close()方法后,任何流操作都会引发 ValueError。并且文档没有提到如何重新打开关闭的流。

如果您想稍后再次使用(重新打开)流,也许您不需要 close() 流。