将pickle.dumps输出写入文件

时间:2014-11-17 13:10:42

标签: python pickle

我有以下代码:

some_dict = {'a':0, 'b':1}
line = "some_dict_b = %s\n" % pickle.dumps(some_dict,2)
exec(line)
decoded_dict = pickle.loads(some_dict_b)
decoded_dict == some_dict

在python 3中,此代码打印为True。在python 2(2.7.8)中,我在exec行中出错。我知道转储在2.7中返回str,而它在3中返回一个字节流。

我正在编写一个程序来解析输入文件中的数据,然后创建某些内存对象,并编写出一个使用这些对象的python脚本。我使用pickle.dumps()在脚本文件中编写这些对象,并按照上面概述的想法将其插入到变量声明行中。但我需要能够在python 2中运行此代码。

我注意到在python 3中,line变量得到了正确转义的每个反斜杠和一个类型:

>>> line
"some_dict_b = b'\\x80\\x02...

在python 2中我得到:

>>> line
'some_dict_b = \x80\x02...

3 个答案:

答案 0 :(得分:1)

Python 3 bytes类型没有具有字符串表示,因此当转换为带有%s的字符串时,对象表示代替。如果您想从对象生成与Python兼容的语法,则可以使用%r格式化器来直接使用表示。

在Python 2中:

>>> import pickle
>>> some_dict = {'a':0, 'b':1}
>>> p = pickle.dumps(some_dict, 2)
>>> print 'string: %s\nrepresentation: %r' % (p, p)
string: ?}q(UaqKUbqKu.
representation: '\x80\x02}q\x00(U\x01aq\x01K\x00U\x01bq\x02K\x01u.'

在Python 3中:

>>> import pickle
>>> some_dict = {'a':0, 'b':1}
>>> p = pickle.dumps(some_dict, 2)
>>> print('string: %s\nrepresentation: %r' % (p, p))
string: b'\x80\x02}q\x00(X\x01\x00\x00\x00bq\x01K\x01X\x01\x00\x00\x00aq\x02K\x00u.'
representation: b'\x80\x02}q\x00(X\x01\x00\x00\x00bq\x01K\x01X\x01\x00\x00\x00aq\x02K\x00u.'

对象表示(使用repr() functionobject.__repr__ special method的输出)通常会尝试为您提供一个表示,可以将其粘贴回Python脚本或交互式提示中以重新创建相同的表达式值。

来自repr()的文档:

  

对于许多类型,此函数尝试返回一个字符串,该字符串在传递给eval()时会产生具有相同值的对象,否则表示形式是包含在尖括号中的字符串,其中包含对象的类型以及通常包括对象的名称和地址的附加信息。

这些都不是pickle特有的,真的。

答案 1 :(得分:0)

每当你想到“我使用exec”时,请再想一想。你没有。而不是像这样评估数据,而是将数据的内容存储在dict本身中。

然后,将数据显式分配给变量。

some_dict = {'a':0, 'b':1}
line = pickle.dumps(some_dict)
decoded_dict = pickle.loads(line)
decoded_dict == some_dict

答案 2 :(得分:0)

您可以在字符串或字节对象上调用repr,然后再将它们插入到行中。

# Python 2
>>> 'some_dict = %s' % repr(pickle.dumps(d))
'some_dict = "(dp0\\nS\'a\'\\np1\\nI12\\nsS\'b\'\\np2\\nI24\\ns."'

# Python 3
>>> 'some_dict = %s' % repr(pickle.dumps(d))
"some_dict = b'\\x80\\x03}q\\x00(X\\x01\\x00\\x00\\x00bq\\x01K\\x18X\\x01\\x00\\x00\\x00aq\\x02K\\x0cu.'"

或使用format方法,使用!r自动调用repr

>>> 'some_dict = {!r}'.format(pickle.dumps(d))
"some_dict = b'\\x80\\x03}q\\x00(X\\x01\\x00\\x00\\x00bq\\x01K\\x18X\\x01\\x00\\x00\\x00aq\\x02K\\x0cu.'"

(也适用于python 2)