6

我腌制了 2.7 中的数据,我这样腌制:

#!/usr/bin/env python2
# coding=utf-8 

import pickle

data = {1: datetime.date(2014, 3, 18), 
       'string-key': u'ünicode-string'}

pickle.dump(data, open('file.pickle', 'wb'))

我发现在 Python 3.4 中加载它的唯一方法是:

data = pickle.load(open('file.pickle', "rb"), encoding='bytes')

现在我的 unicode 字符串很好,但 dict 键是bytes. print(repr(data))给出:

{1: datetime.date(2014, 3, 18), b'string-key': 'ünicode-string'}

有没有人有想法像data[b'string-key']resp 那样重写我的代码。转换所有现有文件?

4

2 回答 2

6

这不是一个真正的答案,而只是一种解决方法。这会将腌制数据转换为 Python 3.4 中的版本 3(在 3.3 中不起作用):

#!/usr/bin/env python3

import pickle, glob

def bytes_to_unicode(ob):
    t = type(ob)
    if t in (list, tuple):
        l = [str(i, 'utf-8') if type(i) is bytes else i for i in ob]
        l = [bytes_to_unicode(i) if type(i) in (list, tuple, dict) else i for i in l]
        ro = tuple(l) if t is tuple else l
    elif t is dict:
        byte_keys = [i for i in ob if type(i) is bytes]
        for bk in byte_keys:
            v = ob[bk]
            del(ob[bk])
            ob[str(bk,'utf-8')] = v
        for k in ob:
            if type(ob[k]) is bytes:
                ob[k] = str(ob[k], 'utf-8')
            elif type(ob[k]) in (list, tuple, dict):
                ob[k] = bytes_to_unicode(ob[k])
        ro = ob
    else:
        ro = ob
        print("unprocessed object: {0} {1}".format(t, ob))
    return ro

for fn in glob.glob('*.pickle'):

    data = pickle.load(open(fn, "rb"), encoding='bytes')
    ndata = bytes_to_unicode(data)
    pickle.dump(ndata, open(fn + '3', "wb"))

Python 文档说:

pickle 序列化格式保证在 Python 版本中向后兼容。

我没有找到pickle.load在 Python 3.3 中处理 Python-2.7 腌制数据的方法——甚至没有找到只包含ints 和dates 的数据。

于 2014-04-04T12:47:07.853 回答
0

看看实现。

您可以子类化Unpickler并覆盖字节反序列化以生成字符串。

于 2014-04-03T14:24:41.680 回答