Pickle能处理多个对象引用吗

14 投票
2 回答
3138 浏览
提问于 2025-04-17 02:23

如果我有两个对象 ab,它们都指向同一个对象 obj,那么当我把这些对象进行“腌制”(也就是把它们保存成一种可以存储的格式)然后再恢复的时候,会发生什么呢?被腌制的数据会“知道” ab 都指向同一个对象,并且在恢复的时候把它们都恢复成同一个对象吗?还是说它们会变成两个不同的对象,虽然一开始它们的内容是一样的?

2 个回答

10

正如 @aix 所说,pickle 可以理解同一个对象的多个引用,但这只是在一次序列化的过程中。也就是说,pickle 每次只会处理一个对象。如果这个对象里面有其他的引用,这些引用在反序列化后会被正确地共享。

但是,如果你调用 pickle 两次,去序列化两个对象,那么这两个对象之间的共享引用就不会被正确保留。这样的话,这个对象就会存在两次。

18

是的,共享对象只会被序列化一次(pickle协议甚至可以处理循环引用)。

根据文档

pickle模块会记录它已经序列化过的对象,这样后面再提到同一个对象时,就不会再序列化一次。而marshal模块则不这样做。

这对递归对象和对象共享都有影响。递归对象是指那些包含自己引用的对象。marshal无法处理这些对象,实际上,尝试对递归对象进行序列化会导致你的Python解释器崩溃。对象共享是指在序列化的对象层级中,有多个地方引用同一个对象。pickle只会存储这些对象一次,并确保所有其他引用都指向主副本。共享对象会保持共享状态,这对可变对象来说非常重要。

撰写回答