Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python StringIO.write doesn't like integer zero?

Why can stream.write output pretty much anything other than zero?

from StringIO import StringIO
v0 = 0
v1 = 1
a = [1, 0, v1, v0, "string", 0.0, 2.0]
stream = StringIO()
for v in a:
    stream.write(v)
    stream.write('\n')
print stream.getvalue()

With Python 2.7.6, running this code produces:

1

1

string

2.0
like image 866
Peter Krnjevic Avatar asked Jun 07 '26 23:06

Peter Krnjevic


2 Answers

The interface for fileobj.write() requires that you write a string, always:

file.write(str)
Write a string to the file.

Emphasis mine.

It is an implementation detail that for StringIO() non-strings just happen to work. The code optimises the 'empty string' case by using:

if not s: return

to avoid doing unnecessary string concatenation. This means that if you pass in any falsey value, such as numeric 0 or None or an empty container, writing doesn't take place.

Convert your objects to a string before writing:

for v in a:
    stream.write(str(v))
    stream.write('\n')

If you used the C-optimised version here you'd have had an error:

>>> from cStringIO import StringIO
>>> f = StringIO()
>>> f.write(0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be string or buffer, not int
like image 71
Martijn Pieters Avatar answered Jun 10 '26 12:06

Martijn Pieters


It looks like it's at StringIO.py, line 214 (function write):

if not s: return

(s being what you are passing to write).

In other words, 'falsy' values (such as None, [], 0, etc) will be discarded.

like image 39
Daniel Avatar answered Jun 10 '26 14:06

Daniel