Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reopening a closed stringIO object in Python 3

So, I create a StringIO object to treat my string as a file:

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

And then I proceed to close the 'file':

>>> f.close()
>>> f.closed
True

Now, when I try to open the 'file' again, Python does not permit me to do so:

>>> 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>

Is there a way to 'reopen' a closed StringIO object? Or should it be declared again using the io.StringIO() method?

Thanks!

like image 418
Prashanth Raghavan Avatar asked May 28 '15 15:05

Prashanth Raghavan


2 Answers

I have a nice hack, which I am currently using for testing (Since my code can make I/O operations, and giving it StringIO is a nice get-around).

If this problem is kind of one time thing:

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)

If this is recurring thing, you can also define a context-manager:

@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

which can be used in the following way:

st = StringIO()
with uncloseable(st):
    f(st) 
# Now st is still open!!!

I hope this helps you with your problem, and if not, I hope you will find the solution you are looking for. Note: This should work exactly the same for other file-like objects.

like image 90
user6035109 Avatar answered Sep 17 '22 04:09

user6035109


The builtin open() creates a file object (i.e. a stream), but in your example, f is already a stream. That's the reason why you get TypeError: invalid file

After the method close() has executed, any stream operation will raise ValueError. And the documentation does not mention about how to reopen a closed stream.

Maybe you need not close() the stream yet if you want to use (reopen) it again later.

like image 21
ldiary Avatar answered Sep 20 '22 04:09

ldiary