Raymond Hettinger wrote:
[Leif K-Brooks]
The obvious workaround is to call buffer.write() with the initial value
instead of passing it to StringIO's constructor,
More than just a workaround, it is the preferred approach.
That makes is easier to switch to cStringIO where initialized objects are
read-only.
Others may find this helpful ; it's a pure Python wrapper for cStringIO
that makes it behave like StringIO in not having initialized objects
readonly. Would it be an idea to extend cStringIO like this in the
standard library? It shouldn't lose performance if used like a standard
cStringIO, but it prevents frustration :-)
David
class StringIO:
def __init__(self, buf = ''):
if not isinstance(buf, (str, unicode)):
buf = str(buf)
self.len = len(buf)
self.buf = cStringIO.StringIO()
self.buf.write(buf)
self.buf.seek(0)
self.pos = 0
self.closed = 0
def __iter__(self):
return self
def next(self):
if self.closed:
raise StopIteration
r = self.readline()
if not r:
raise StopIteration
return r
def close(self):
"""Free the memory buffer.
"""
if not self.closed:
self.closed = 1
del self.buf, self.pos
def isatty(self):
if self.closed:
raise ValueError, "I/O operation on closed file"
return False
def seek(self, pos, mode = 0):
if self.closed:
raise ValueError, "I/O operation on closed file"
self.buf.seek(pos, mode)
self.pos = self.buf.tell()
def tell(self):
if self.closed:
raise ValueError, "I/O operation on closed file"
return self.pos
def read(self, n = None):
if self.closed:
raise ValueError, "I/O operation on closed file"
if n == None:
r = self.buf.read()
else:
r = self.buf.read(n)
self.pos = self.buf.tell()
return r
def readline(self, length=None):
if self.closed:
raise ValueError, "I/O operation on closed file"
if length is not None:
r = self.buf.readline(length)
else:
r = self.buf.readline(length)
self.pos = self.buf.tell()
return r
def readlines(self):
if self.closed:
raise ValueError, "I/O operation on closed file"
lines = self.buf.readlines()
self.pos = self.buf.tell()
return lines
def truncate(self, size=None):
if self.closed:
raise ValueError, "I/O operation on closed file"
self.buf.truncate(size)
self.pos = self.buf.tell()
self.buf.seek(0, 2)
self.len = self.buf.tell()
self.buf.seek(self.pos)
def write(self, s):
if self.closed:
raise ValueError, "I/O operation on closed file"
origpos = self.buf.tell()
self.buf.write(s)
self.pos = self.buf.tell()
if origpos + len(s) > self.len:
self.buf.seek(0, 2)
self.len = self.buf.tell()
self.buf.seek(self.pos)
def writelines(self, lines):
if self.closed:
raise ValueError, "I/O operation on closed file"
self.buf.writelines(lines)
self.pos = self.buf.tell()
self.buf.seek(0, 2)
self.len = self.buf.tell()
self.buf.seek(self.pos)
def flush(self):
if self.closed:
raise ValueError, "I/O operation on closed file"
self.buf.flush()
def getvalue(self):
if self.closed:
raise ValueError, "I/O operation on closed file"
return self.buf.getvalue()