Pickle能处理多个对象引用吗
如果我有两个对象 a
和 b
,它们都指向同一个对象 obj
,那么当我把这些对象进行“腌制”(也就是把它们保存成一种可以存储的格式)然后再恢复的时候,会发生什么呢?被腌制的数据会“知道” a
和 b
都指向同一个对象,并且在恢复的时候把它们都恢复成同一个对象吗?还是说它们会变成两个不同的对象,虽然一开始它们的内容是一样的?
2 个回答
10
正如 @aix 所说,pickle
可以理解同一个对象的多个引用,但这只是在一次序列化的过程中。也就是说,pickle 每次只会处理一个对象。如果这个对象里面有其他的引用,这些引用在反序列化后会被正确地共享。
但是,如果你调用 pickle 两次,去序列化两个对象,那么这两个对象之间的共享引用就不会被正确保留。这样的话,这个对象就会存在两次。
18
是的,共享对象只会被序列化一次(pickle协议甚至可以处理循环引用)。
根据文档:
pickle
模块会记录它已经序列化过的对象,这样后面再提到同一个对象时,就不会再序列化一次。而marshal
模块则不这样做。这对递归对象和对象共享都有影响。递归对象是指那些包含自己引用的对象。
marshal
无法处理这些对象,实际上,尝试对递归对象进行序列化会导致你的Python解释器崩溃。对象共享是指在序列化的对象层级中,有多个地方引用同一个对象。pickle
只会存储这些对象一次,并确保所有其他引用都指向主副本。共享对象会保持共享状态,这对可变对象来说非常重要。