如何修复Python中的unicode/cPickle错误?

1 投票
3 回答
8315 浏览
提问于 2025-04-15 23:23
ids = cPickle.loads(gem.value)

loads() argument 1 must be string, not unicode

当然可以!请把你想要翻译的内容发给我,我会帮你用简单易懂的语言解释清楚。

3 个回答

-1

你可以通过把 gem.value 变成字符串来解决这个问题,而不是用unicode格式。

可以使用 str(gem.value) 这个方法。

1

使用 cPickle.dumps() 的结果是一个 str 对象,而不是 unicode 对象。你需要找到代码中解码这个被“腌制”的 str 对象的那一步,并且跳过它。

不要试图把你的 unicode 对象转换成 str 对象。两次错误并不会变成正确的。举个例子(Python 2.6):

>>> import cPickle
>>> ps = cPickle.dumps([1,2,3], -1)
>>> ps
'\x80\x02]q\x01(K\x01K\x02K\x03e.'
>>> ups = ps.decode('latin1')
>>> str(ups)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\x80' in position 0: ordinal not in range(128)
>>>

你可能正在使用默认的(效率低下的)协议0,这会产生“人类可读”的输出:

>>> ps = cPickle.dumps([1,2,3])
>>> ps
'(lp1\nI1\naI2\naI3\na.'
>>>

这大概是ASCII格式(但没有文档说明),所以 str(gem.value) 的这种做法可能会“有效”:

>>> ps == str(unicode(ps))
True
>>>
8

cPickle.loads 需要一个字节串(byte string),而 cPickle.dumps 输出的正是这种格式。但是你给它的是一个 Unicode 字符串。你需要把这个 Unicode 字符串“编码”一下,才能得到最开始 dumps 给你的字节串。不过,猜测你不小心用了什么编码方式就有点难了——可能是 latin-1 或者 utf-8(如果是 ascii,那就不用担心,这两种编码都能很好地解码),也可能是 utf-16……在不知道 gem 是什么,以及你是如何从 cPickle.dumps 的输出中设置它的 value 的情况下,真的是很难猜测!

撰写回答