29

I'm trying to learn how to use the pickle module in Python:

import pickle
x = 123
f = open('data.txt','w')
pickle.dump(x,f)

Here's what I get:

Traceback (most recent call last):
  File "D:\python\test.py", line 5, in <module>
    pickle.dump(x,f)
TypeError: must be str, not bytes

However, this code works just fine:

import pickle
dump = pickle.dump(123)
print(dump)


What am I doing wrong?

PLNech
  • 3,087
  • 1
  • 23
  • 52
Sergey
  • 47,222
  • 25
  • 87
  • 129
  • Just something worth mentioning: for all file modes in Python, you should add a `'b'` to the end of the string, even if it's only `'rb'`, since it's platform independent. – Edwin Jan 02 '12 at 17:30
  • @Edwin: It doesn't do platform-specific newline transliterations, but in 3.x there's an important different: Files opened in binary mode handle only bytes, files opened in text mode handle only text ("unicode"). While binary mode certainly makes sense for binary data, and text mode may not apply in some other cases, your suggestion is far too general. If you'd just going to decode the bytes to text, opening in binary mode is usually nonsense. It's easier and more robust to let Python handle that, and it's better at guessing encodings than we are at hardcoding encodings. –  Jan 02 '12 at 17:35
  • @delnan Ah, ok; I just remembered reading that somewhere on the python.org site. – Edwin Jan 02 '12 at 19:53

2 Answers2

43

The problem is that you're opening the file in text mode. You need to use binary here:

>>> f = open('data.txt','w')
>>> pickle.dump(123,f)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: must be str, not bytes
>>> 
>>> f = open('data.txt','wb')
>>> pickle.dump(123,f)
>>> 
DSM
  • 342,061
  • 65
  • 592
  • 494
  • 4
    @SrinivasReddyThatiparthy: were you using Python 3? Things changed. – DSM Jan 02 '12 at 17:11
  • 1
    @SrinivasReddyThatiparthy: no, I mean that it _would_ have worked in the past, and only stopped working in Python 3. – DSM Jan 02 '12 at 17:15
2

The write method for file-like objects, only accept a single string argument. The dumps method in the pickle module automatically casts arguments as strings, whereas the the dump method will write a pickled representation of the object to the open file. Since 123 is not a string it throws the TypeError error.

This is acknowledged in pickle.dump documentation.

garnertb
  • 9,454
  • 36
  • 38