因此,我创建了一个StringIO对象来将我的字符串视为文件:
>>> a = 'Me, you and them\n'
>>> import io
>>> f = io.StringIO(a)
>>> f.read(1)
'M'
然后我继续关闭'文件':
>>> f.close()
>>> f.closed
True
现在,当我再次尝试打开'文件'时,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>
有没有办法'重新打开'一个已关闭的StringIO对象?或者是否应该使用io.StringIO()方法再次声明?
谢谢!
答案 0 :(得分:4)
内置open()创建一个文件对象(即流),但在您的示例中,f已经是一个流。 这就是你得到TypeError:无效文件
的原因执行方法close()后,任何流操作都会引发ValueError。 文档没有提到如何重新打开封闭流。
如果您想稍后再次使用(重新打开),可能还需要关闭()流。
答案 1 :(得分:4)
我有一个不错的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)
如果这是重复发生的事情,则还可以定义一个上下文管理器:
@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
可以通过以下方式使用:
st = StringIO()
with uncloseable(st):
f(st)
# Now st is still open!!!
我希望这可以帮助您解决问题,如果没有,希望您能找到所需的解决方案。 注意:这对于其他类似文件的对象应该完全相同。
答案 2 :(得分:2)
不,没有办法重新打开io.StringIO
对象。相反,只需使用io.StringIO()
创建一个新对象。
在close()
对象上调用io.StringIO
会丢弃“文件内容”数据,因此无论如何重新打开都无法访问该文件。
如果您需要数据,请在关闭前致电getvalue()
。
另请参见the StringIO
documentation:
调用close()方法时,将丢弃文本缓冲区。
在这里:
getvalue()
返回包含缓冲区全部内容的str。
答案 3 :(得分:0)
在f.close()
上将其从内存中删除。基本上,您正在做一个deref x,调用x;您正在寻找不存在的内存位置。
以下是您可以做的:
import io
a = 'Me, you and them\n'
f = io.StringIO(a)
f.read(1)
f.close()
# Put the text form a without the first char into StringIO.
p = io.StringIO(a[1:]).
# do some work with p.
我认为您的困惑来自将io.StringIO
视为块设备上的文件。如果您使用open()
而不是StringIO
,那么在您的示例中您将是正确的,并且可以重新打开文件。 StringIO
不是文件。这是内存中文件对象的StringIO
,但它实际上也存在于块设备上。 StringIO
只是一个缓冲区,是其中存储数据的暂存区。当您调用open()
时,会创建一个缓冲区,但是块设备上仍然有数据。
也许这就是您想要的
fo = open('f.txt','w+')
fo.write('Me, you and them\n')
fo.read(1)
fo.close()
# reopen the now closed file `f`
p = open('f.txt','r')
# do stuff with p
p.close()
在这里,我们正在将字符串写入块设备,因此,当我们关闭文件时,写入文件的信息将在关闭后保留。因为这是在运行progarm的目录中创建一个文件,所以最好给该文件扩展名。例如,您可以将文件命名为f.txt
而不是f
。