使用pickle.dump - TypeError: 必须是字符串,而不是字节

341

我正在使用Python3.3,在尝试pickle一个简单的字典时,遇到了一个晦涩的错误。

以下是代码:

import os
import pickle
from pickle import *
os.chdir('c:/Python26/progfiles/')

def storvars(vdict):      
    f = open('varstor.txt','w')
    pickle.dump(vdict,f,)
    f.close()
    return

mydict = {'name':'john','gender':'male','age':'45'}
storvars(mydict)

然后我得到:

Traceback (most recent call last):
  File "C:/Python26/test18.py", line 31, in <module>
    storvars(mydict)
  File "C:/Python26/test18.py", line 14, in storvars
    pickle.dump(vdict,f,)
TypeError: must be str, not bytes
3个回答

557

输出文件需要以二进制模式打开:

f = open('varstor.txt','w')

需要是:

f = open('varstor.txt','wb')

29
在遇到完全相同的问题后,我看到在 pickle.dump()pickle.load()文档中提到了需要进行“二进制”读写的必要性。这个提示只是在函数解释的中间部分简单提到了两次。有人应该把这个提示表述得更清楚明白。 - Matthew
11
我向Python项目提交了#24159。或许可以做一些改进,以改善这种及类似情况的体验。 - Jason R. Coombs
值得一提的是,@Matthew在上面的评论中提供的文档链接并没有提到在“函数解释的中间附近”需要二进制文件。也许他们当时已经更改了?话虽如此,回过头来看,我们可以搜索关键词“二进制”,然后在该文档页面的顶部第一段/句子中就会提到它。 - RayLuo
这在 Python 2 中是不需要的,就这样吧。我在将代码从2转换为3时遇到了相同的错误。 - abcd

43

我刚遇到了同样的问题。在Python 3中,必须指定二进制模式'wb'、'rb',而在Python 2x中则不需要。如果你按照基于Python 2x的教程操作,那就会出现这种情况。

import pickle

class MyUser(object):
    def __init__(self,name):
        self.name = name

user = MyUser('Peter')

print("Before serialization: ")
print(user.name)
print("------------")
serialized = pickle.dumps(user)
filename = 'serialized.native'

with open(filename,'wb') as file_object:
    file_object.write(serialized)

with open(filename,'rb') as file_object:
    raw_data = file_object.read()

deserialized = pickle.loads(raw_data)


print("Loading from serialized file: ")
user2 = deserialized
print(user2.name)
print("------------")

1

pickle使用二进制协议,因此只接受二进制文件。正如文档中第一句所说,“pickle模块实现了用于序列化和反序列化的二进制协议”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接