23

I must be doing something obviously wrong here. But what is it, and how do I fix?

Python 2.6.5 (r265:79096, Mar 19 2010, 21:48:26) [MSC v.1500 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import io
>>> f1 = io.open('test.txt','w')
>>> f1.write('bingo')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\appl\python\2.6.5\lib\io.py", line 1500, in write
    s.__class__.__name__)
TypeError: can't write str to text stream

edit: In my real application, I won't have a constant string, I'll have a regular string... if unicode is the issue, how do I convert to what io.open requires?

Jason S
  • 184,598
  • 164
  • 608
  • 970
  • Any reason you're using `io.open()` instead of the built-in function `open()`? – martineau Dec 22 '10 at 19:50
  • Because I was referred to the io classes with this other question: http://stackoverflow.com/questions/4512733/python-equivalent-of-java-outputstream/4512880#4512880 – Jason S Dec 22 '10 at 19:51

5 Answers5

39

The io module is a fairly new python module (introduced in Python 2.6) that makes working with unicode files easier. Its documentation is at: http://docs.python.org/library/io.html

If you just want to be writing bytes (Python 2's "str" type) as opposed to text (Python 2's "unicode" type), then I would recommend you either skip the io module, and just use the builtin "open" function, which gives a file object that deals with bytes:

>>> f1 = open('test.txt','w')

Or, use 'b' in the mode string to open the file in binary mode:

>>> f1 = io.open('test.txt','wb')

Read the docs for the io module for more details: http://docs.python.org/library/io.html

Edward Loper
  • 15,374
  • 7
  • 43
  • 52
13

Try:

>>> f1.write(u'bingo')      # u specifies unicode

Reference

user225312
  • 126,773
  • 69
  • 172
  • 181
  • 2
    `unicode(s)` will convert your byte string (regular string) to a Unicode string. – user225312 Dec 22 '10 at 19:50
  • If Jason has a non-ascii byte string, then unicode(s) will just raise an exception. If he's working with bytes (and not unicode aka text), then he's probably better off using a file object that deals with bytes -- either `f=open('file','w')` or `f=io.open('file', 'wb')`. – Edward Loper Dec 22 '10 at 19:58
5

Have you tried writing a Unicode string, instead of just a str? I.e.,

fq.write(u"bingo")

I'm on Mac OS X, but when I tried to write a str, I got the error

TypeError: must be unicode, not str

Writing a Unicode string worked, though.

mipadi
  • 398,885
  • 90
  • 523
  • 479
4
f = open("test.txt", "w")
f.write('bingo')
f.close()

equivalently,

with open("test.txt", "w") as f:
    f.write('bingo')

and the termination of the block closes the file for you.

mbm
  • 1,902
  • 2
  • 19
  • 28
3

The io module differs from the old open in that it will make a big difference between binary and text files. If you open a file in text mode, reading will return Unicode text objects (called unicode in Python 2 and str in Python 3) and writing requires that you give it unicode objects as well.

If you open in binary mode, you will get 8-bit sequential data back, and that's what you need to write. In Python 2 you use str for this, in Python 3 bytes.

You are using Python 2, and trying to write str to a file opened in text mode. That won't work. Use Unicode.

Lennart Regebro
  • 167,292
  • 41
  • 224
  • 251