python - pickle 和 deepcopy 的关系

标签 python pickle python-2.x deep-copy

picklecopy.deepcopy究竟是什么关系?它们共享哪些机制?如何共享?

很明显,这两者是密切相关的操作,并且共享一些机制/协议(protocol),但我无法深入了解细节。

我发现的一些(令人困惑的)事情:

  1. 如果一个类定义了 __[gs]etstate__,它们会在其实例的 deepcopy 上被调用。起初这让我很惊讶,因为我认为它们是 pickle 特有的,但后来我发现 Classes can use the same interfaces to control copying that they use to control pickling 。但是,没有文档说明 如何 __[gs]etstate__ 在深度复制时使用(如何使用从 __getstate__ 返回的值,是什么传递给 __setstate__?)
  2. deepcopy 的简单替代实现是 pickle.loads(pickle.dumps(obj))。但是,这不可能等同于 deepcopy'ing,因为如果一个类定义了 __deepcopy__ 操作,则不会使用基于 pickle 的 deepcopy 实现来调用它。 (我还偶然发现了一种说法,即 deepcopy 比 pickle 更通用,并且有很多类型可以 deepcopy,但不能 pickle。)

(1)表示共性,(2)表示pickledeepcopy的区别。

除此之外,我发现了以下两个相互矛盾的陈述:

copy_reg: The pickle, cPickle, and copy modules use those functions when pickling/copying those objects

The copy module does not use the copy_reg registration module

一方面,这表明 pickledeepcopy 之间的关系/共同点,另一方面,这也导致了我的困惑......

[我的经验是使用 python2.7,但我也很感激任何关于 python2 和 python3 之间pickle/deepcopy 差异的指针]

最佳答案

您不应被 (1) 和 (2) 混淆。一般来说,Python 会尝试为缺失的方法包含合理的后备方案。 (例如,定义 __getitem__ 以拥有一个可迭代的类就足够了,但同时实现 __iter__ 可能更有效。类似 之类的操作__add__,以及可选的 __iadd__ 等)

__deepcopy__deepcopy() 将寻找的最专业的方法,但如果它不存在,回退到 pickle 协议(protocol)是明智之举.它并没有真正调用dumps()/loads(),因为它不依赖中间表示为字符串,而是会间接利用__getstate____setstate__(通过 __reduce__),如您所见。

目前,the documentation仍然状态

… The copy module does not use the copy_reg registration module.

但这似乎是 a bug that has been fixed in the meantime (可能是2.7分支在这里没有得到足够的重视)。

还请注意,这已非常深入地集成到 Python 中(至少现在是这样); object 类本身实现了 __reduce__ (及其版本化的 _ex 变体),它引用 copy_reg.__newobj__ 来创建给定对象的新实例-派生类。

关于python - pickle 和 deepcopy 的关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22388854/

相关文章:

python - 如何使用 pickle 将数据保存到磁盘?

python - python中以0开头的数字是什么意思?

python - 为什么新样式类和旧样式类在这种情况下有不同的行为?

python sqlite3插入表错误: cursor is not connected?

python - Python上的Elasticsearch DSL无法生成分数

python - python 中存在多个匹配项时删除两个模式之间的行

python - 根据条件设置具有相同编号的计数器或行

python - 更改已保存 pickle 的导入库

python - 类型错误 : 'str' does not support the buffer interface - python

Python 2, map 在简单情况下不等同于列表理解;长度依赖