Pickling 是一种迷你语言,可用于将相关状态从 python 对象转换为字符串,其中该字符串唯一地表示该对象。然后 (un)pickling 可用于将字符串转换为活动对象,方法是从创建字符串的保存状态“重建”对象。
>>> import pickle
>>>
>>> class Foo(object):
... y = 1
... def __init__(self, x):
... self.x = x
... return
... def bar(self, y):
... return self.x + y
... def baz(self, y):
... Foo.y = y
... return self.bar(y)
...
>>> f = Foo(2)
>>> f.baz(3)
5
>>> f.y
3
>>> pickle.dumps(f)
"ccopy_reg\n_reconstructor\np0\n(c__main__\nFoo\np1\nc__builtin__\nobject\np2\nNtp3\nRp4\n(dp5\nS'x'\np6\nI2\nsb."
您在这里可以看到,pickle 不保存类的源代码,但确实存储了对类定义的引用。基本上,你几乎可以阅读挑选出来的字符串……它说(粗略翻译)“调用 copy_reg 的重构器,其中参数是 __main__.Foo 定义的类,然后做其他事情”。另一件事是实例的保存状态。如果您看得更深,您可以提取“字符串 x”设置为“整数 2”(大致为:S'x'\np6\nI2)。这实际上是字典条目的腌制字符串的剪辑部分……dict 是f.__dict__,即{'x': 2}。如果您查看pickle 的源代码,它非常清楚地给出了从python 到腌制字节码的每种类型的对象和操作的翻译。
另请注意,酸洗语言有不同的变体。默认为协议 0,更易于阅读。还有协议 2,如下所示(以及 1,3 和 4,具体取决于您使用的 python 版本)。
>>> pickle.dumps([1,2,3])
'(lp0\nI1\naI2\naI3\na.'
>>>
>>> pickle.dumps([1,2,3], -1)
'\x80\x02]q\x00(K\x01K\x02K\x03e.'
同样,它仍然是酸洗语言的方言,您可以看到协议 0 字符串表示“获取列表,包括 I1、I2、I3”,而协议 2 更难阅读,但表示相同事物。第一个位 \x80\x02 表示它是协议 2 - 然后你有 ] 它说它是一个列表,然后你可以再次看到整数 1,2,3 在那里。同样,检查 pickle 的源代码以查看 pickle 语言的确切映射。
要将酸洗反转为字符串,请使用 load/loads。
>>> p = pickle.dumps([1,2,3])
>>> pickle.loads(p)
[1, 2, 3]