python - cPickle - pickle 同一对象的不同结果

标签 python serialization pickle

有没有人能解释testLookups() 下的注释 code snippet ?

我已经运行了代码,确实评论说的是真的。但是我想了解为什么它是真的,即为什么 cPickle 根据引用方式为同一对象输出不同的值。

和引用计数有关系吗?如果是这样,那不是某种错误 - 即 pickle 和反序列化的对象将具有异常高的引用计数并且实际上永远不会被垃圾收集?

最佳答案

不能保证看似相同的对象会产生相同的 pickle 字符串。

pickle 协议(protocol)是一个虚拟机,pickle 字符串是该虚拟机的程序。对于给定的对象,存在多个 pickle 字符串(=程序),它们将准确地重建该对象。

举一个例子:

>>> from cPickle import dumps
>>> t = ({1: 1, 2: 4, 3: 6, 4: 8, 5: 10}, 'Hello World', (1, 2, 3, 4, 5), [1, 2, 3, 4, 5])
>>> dumps(({1: 1, 2: 4, 3: 6, 4: 8, 5: 10}, 'Hello World', (1, 2, 3, 4, 5), [1, 2, 3, 4, 5]))
"((dp1\nI1\nI1\nsI2\nI4\nsI3\nI6\nsI4\nI8\nsI5\nI10\nsS'Hello World'\np2\n(I1\nI2\nI3\nI4\nI5\ntp3\n(lp4\nI1\naI2\naI3\naI4\naI5\nat."
>>> dumps(t)
"((dp1\nI1\nI1\nsI2\nI4\nsI3\nI6\nsI4\nI8\nsI5\nI10\nsS'Hello World'\n(I1\nI2\nI3\nI4\nI5\nt(lp2\nI1\naI2\naI3\naI4\naI5\natp3\n."

这两个 pickle 字符串在 p 操作码的使用上有所不同。该操作码接受一个整数参数,其功能如下:

  name='PUT'    code='p'   arg=decimalnl_short

  Store the stack top into the memo.  The stack is not popped.

  The index of the memo location to write into is given by the newline-
  terminated decimal string following.  BINPUT and LONG_BINPUT are
  space-optimized versions.

长话短说,两个pickle字符串基本等价。

我还没有尝试确定生成的操作码差异的确切原因。这很可能与被序列化的对象的引用计数有关。然而,很明显,这样的差异不会对重建的对象产生影响。

关于python - cPickle - pickle 同一对象的不同结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7501577/

相关文章:

python - Django 规则对象权限

python - 如何迭代一系列排列?

python - Django ORM 左连接与 GROUP BY 和 SUM

symfony - JMS 序列化程序 : how to use camel case for properties

python - pickle.dump 由于 GIL 而阻塞多线程 python 应用程序中的主线程

python - joblib.load 和 pickle.load 错误 "No attribute ' XGBoostLabelEncoder'"

python - Python 中的密码测试

scala - 为 Spark 序列化 Scalaz 订单

java - 不可序列化类中的非 transient 不可序列化实例字段?

Python多进程无法pickle opencv videocapture对象