How to Use Stringio in Python3

Python 3.4 : cStringIO vs. StringIO

StringIO no longer exists in 3.x. Use either io.StringIO for text or io.BytesIO for bytes.

io.StringIO vs open() in Python 3

The difference is: open takes a file name (and some other arguments like mode or encoding), io.StringIO takes a plain string and both return file-like objects.

Hence:

  • Use open to read files ;
  • Use StringIO when you need a file-like object and you want to pass the content of a string.

An example with StringIO:

import csv
import io

reader = csv.reader(io.StringIO("a,b,c\n1,2,3"))
print ([r for r in reader])
# output [['a', 'b', 'c'], ['1', '2', '3']]

It's very useful because you can use a string where a file was expected.

In the usual case, with a csv file on your disk, you would write something like:

with open(<path/to/file.csv>, ...) as f:
reader = csv.reader(f, ...)

What is StringIO in python used for in reality?

It's used when you have some API that only takes files, but you need to use a string. For example, to compress a string using the gzip module in Python 2:

import gzip
import StringIO

stringio = StringIO.StringIO()
gzip_file = gzip.GzipFile(fileobj=stringio, mode='w')
gzip_file.write('Hello World')
gzip_file.close()

stringio.getvalue()

python 3.x ImportError: No module named 'cStringIO'

From Python 3.0 changelog:

The StringIO and cStringIO modules are gone. Instead, import the io module and use io.StringIO or io.BytesIO for text and data respectively.

From the Python 3 email documentation it can be seen that io.StringIO should be used instead:

from io import StringIO
from email.generator import Generator

fp = StringIO()
g = Generator(fp, mangle_from_=True, maxheaderlen=60)
g.flatten(msg)
text = fp.getvalue()

Python pip3 install StringIO Not Found for url: https://pypi.org/simple/stringio/

You don't need to use pip3:

Sample Image

Use:

import io

hi = io.StringIO("hi")

Sample Image

StringIO portability between python2 and python3 when capturing stdout

You replaced the Python 2 bytes-only sys.stdout with one that only takes Unicode. You'll have to adjust your strategy on the Python version here, and use a different object:

try:
# Python 2
from cStringIO import StringIO
except ImportError:
# Python 3
from io import StringIO

and remove the io. prefix in your context manager:

origout,  sys.stdout = sys.stdout, StringIO()

The cStringIO.StringIO object is the Python 2 equivalent of io.BytesIO; it requires that you write plain bytestrings, not aunicode objects.

You can also use io.BytesIO in Python 2, but then you want to test if sys.stdout is a io.TextIOBase subclass; if it is not, replace the object with a binary BytesIO, object, otherwise use a StringIO object:

import io

if isinstance(sys.stdout, io.TextIOBase):
# Python 3
origout, sys.stdout = sys.stdout, io.StringIO()
else:
# Python 2 or an unorthodox binary stdout setup
origout, sys.stdout = sys.stdout, io.BytesIO()


Related Topics



Leave a reply



Submit