泡菜和深度复制之间的关系 [英] Relationship between pickle and deepcopy

查看:83
本文介绍了泡菜和深度复制之间的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

picklecopy.deepcopy 之间的确切关系是什么?它们共享哪些机制,以及如何共享?

What exactly is the relationship between pickle and copy.deepcopy? What mechanisms do they share, and how?

很明显,这两个是密切相关的操作,并且共享一些机制/协议,但是我无法将细节笼罩着.

It is clear the two are closely-related operations, and share some of the mechanisms/protocols, but I can't wrap my head around the details.

我发现的一些(令人困惑的)东西

Some (confusing) things I found out:

  1. 如果类定义了__[gs]etstate__,则会在其实例的deepcopy上调用它们.一开始这让我感到惊讶,因为我认为它们特定于pickle,但是后来我发现 类可以使用与控制酸洗相同的界面来控制复制 .但是,没有关于深度复制时如何使用 __[gs]etstate__的文档(如何使用从__getstate__返回的值,是什么传递给__setstate__?)
  2. deepcopy的幼稚替代实现为pickle.loads(pickle.dumps(obj)).但是,这可能不等同于深度复制,因为如果类定义了__deepcopy__操作,则不会使用此基于pickle的深度复制实现来调用它. (我也偶然发现了一种说法,即深拷贝比pickle更通用,并且有许多类型是可深拷贝的,但不能进行pickle.)
  1. If a class defines __[gs]etstate__, they get called upon a deepcopy of its instances. This surprised me at first, because I thought they are specific to pickle, but then I found that Classes can use the same interfaces to control copying that they use to control pickling. However, there's no documentation of how __[gs]etstate__ is used when deepcopying (how the value returned from __getstate__ is used, what is being passed to __setstate__?)
  2. A naive alternative implementation of deepcopy would be pickle.loads(pickle.dumps(obj)). However, this can't possibly be equivalent to deepcopy'ing, because if a class defines a __deepcopy__ operation, it would not be invoked using this pickle-based implementation of deepcopy. (I also stumbled upon a statement that deepcopy is more general than pickle, and there are many types which are deepcopyable, but not pickleable.)

(1)表示共性,而(2)表示pickledeepcopy之间的差异.

(1) indicates a commonality, while (2) indicates a difference between pickle and deepcopy.

最重要的是,我发现了以下两个矛盾的说法:

On top of that, I found these two contradictory statements:

copy_reg :酸洗,cPickle和复制模块在酸洗/复制这些对象时会使用这些功能.

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

复制模块未使用copy_reg注册模块

The copy module does not use the copy_reg registration module

一方面,这是pickledeepcopy之间的关系/共性的另一种指示,另一方面,这加剧了我的困惑...

This, on one hand, is another indication of a relationship/commonality between pickle and deepcopy, and on the other hand, contributes to the my confusion...

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

推荐答案

您不应被(1)和(2)所迷惑.通常,Python会尝试为遗漏的方法提供合理的后备方法. (例如,定义__getitem__以便具有可迭代的类就足够了,但是也可以实现__iter__效率更高.类似于__add__的操作,并带有可选的__iadd__等.)

You should not be confused by (1) and (2). In general, Python tries to include sensible fall-backs for missing methods. (For instance, it is enough to define __getitem__ in order to have an iterable class, but it may be more efficient to also implement __iter__. Similar for operations like __add__, with optional __iadd__ etc.)

__deepcopy__deepcopy()会寻找的最专门的方法,但是,如果它不存在,则退回使用pickle协议是明智的选择.它并没有真正调用dumps()/loads(),因为它不依赖中间表示形式为字符串,而是像您一样间接使用__getstate____setstate__(通过__reduce__).观察到.

__deepcopy__ is the most specialized method that deepcopy() will look for, but if it does not exists, falling back to the pickle protocol is a sensible thing to do. It does not really call dumps()/loads(), because it does not rely on the intermediate representation to be a string, but it will indirectly make use of __getstate__ and __setstate__ (via __reduce__), as you observed.

当前,文档仍然说明

...复制模块不使用copy_reg注册模块.

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

,但这似乎是同时已修复的错误(可能是2.7分支)在这里没有引起足够的重视.)

but that seems to be a bug that has been fixed in the meantime (possibly, the 2.7 branch has not gotten enough attention here).

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

Also note that this is pretty deeply integrated into Python (at least nowadays); the object class itself implements __reduce__ (and its versioned _ex variant), which refers to copy_reg.__newobj__ for creating fresh instances of the given object-derived class.

这篇关于泡菜和深度复制之间的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆