from copy import*
a=[1,2,3,4]
c={'a':'aaa'}
print c
#{'a': 'aaa'}
b=deepcopy(a,c)
print b
print c
# print {'a': 'aaa', 10310992: 3, 10310980: 4, 10311016: 1, 11588784: [1, 2, 3, 4, [1, 2, 3, 4]], 11566456: [1, 2, 3, 4], 10311004: 2}
为什么要打印那个
请尽量使用代码,而不是文字,因为我的英文不是很好,谢谢
在 django.utils.tree.py 中
def __deepcopy__(self, memodict):
"""
Utility method used by copy.deepcopy().
"""
obj = Node(connector=self.connector, negated=self.negated)
obj.__class__ = self.__class__
obj.children = deepcopy(self.children, memodict)
obj.subtree_parents = deepcopy(self.subtree_parents, memodict)
return obj
import copy
memo = {}
x1 = range(5)
x2=range(6,9)
x3=[2,3,4,11]
y1 = copy.deepcopy(x1, memo)
y2=copy.deepcopy(x2, memo)
y3=copy.deepcopy(x3,memo)
print memo
print id(y1),id(y2),id(y3)
y1[0]='www'
print y1,y2,y3
print memo
打印:
{10310992: 3, 10310980: 4, 10311016: 1, 11588784: [0, 1, 2, 3, 4, [0, 1, 2, 3, 4]], 10311028: 0, 11566456: [0, 1, 2, 3, 4], 10311004: 2}
{11572448: [6, 7, 8], 10310992: 3, 10310980: 4, 10311016: 1, 11572368: [2, 3, 4, 11], 10310956: 6, 10310896: 11, 10310944: 7, 11588784: [0, 1, 2, 3, 4, [0, 1, 2, 3, 4], 6, 7, 8, [6, 7, 8], 11, [2, 3, 4, 11]], 10311028: 0, 11566456: [0, 1, 2, 3, 4], 10310932: 8, 10311004: 2}
11572408 11581280 11580960
['www', 1, 2, 3, 4] [6, 7, 8] [2, 3, 4, 11]
{11572448: [6, 7, 8], 10310992: 3, 10310980: 4, 10311016: 1, 11572368: [2, 3, 4, 11], 10310956: 6, 10310896: 11, 10310944: 7, 11588784: [0, 1, 2, 3, 4, [0, 1, 2, 3, 4], 6, 7, 8, [6, 7, 8], 11, [2, 3, 4, 11]], 10311028: 0, 11566456: ['www', 1, 2, 3, 4], 10310932: 8, 10311004: 2}
最佳答案
上面没有人给出一个很好的例子来说明如何使用它。
这是我的做法:
def __deepcopy__(self, memo):
copy = type(self)()
memo[id(self)] = copy
copy._member1 = self._member1
copy._member2 = deepcopy(self._member2, memo)
return copy
member1
是不需要深度复制的对象(如字符串或整数),而 member2
是需要深度复制的对象,如另一种自定义类型或列表或字典。
我已经在高度纠结的对象图上使用了上面的代码并且效果很好。
如果你还想让你的类 pickleable(用于文件保存/加载),getstate/setstate 没有类似的 memo 参数,换句话说 pickle系统会以某种方式跟踪已引用的对象,因此您无需担心。
以上适用于您继承自的 PyQt5 类(以及 pickling - 例如我可以深度复制或 pickle 自定义 QMainWindow、QWidget、QGraphicsItem 等)
如果您的构造函数中有一些创建新对象的初始化代码,例如创建新 CustomScene(QGraphicsScene) 的 CustomWidget(QWidget),但是您想将场景从一个 CustomWidget 腌制或复制到一个新的一个,然后一种方法是在你的 __init__
中创建一个 new=True
参数并说:
def __init__(..., new=True):
....
if new:
self._scene = CustomScene()
def __deepcopy__(self, memo):
copy = type(self)(..., new=False)
....
copy._scene = deepcopy(self._scene, memo)
....
这确保您不会创建 CustomScene(或一些进行大量初始化的大类)两次!您还应该在 __setstate__
方法中使用相同的设置 (new=False
),例如:
def __setstate__(self, data):
self.__init__(...., new=False)
self._member1 = data['member 1']
.....
还有其他方法可以解决上述问题,但这是我总结并经常使用的方法。
为什么我也谈到酸洗?因为通常在任何应用程序中您都需要这两者,并且您同时维护它们。如果您将成员添加到您的类中,您会将其添加到 setstate、getstate、和 deepcopy 代码中。我会制定一条规则,对于您创建的任何新类,如果您计划在您的应用程序中复制/粘贴文件保存/加载,则创建上述三种方法。替代方案是 JSON 并自己保存/加载,但是您还有很多工作要做,包括内存。
因此,要支持以上所有内容,您需要 __deepcopy__、__setstate__ 和 __getstate__
方法并导入 deepcopy:
from copy import deepcopy
,当你编写你的 pickle loader/saver 函数时(你调用 pickle.load()/pickle.dump()
来加载/保存你的对象层次结构/图表)做 import _pickle as pickle
以获得最佳速度(_pickle
是一些更快的 C impl,通常与您的应用要求兼容)。
关于python - deepcopy的第二个参数memo的作用是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1950563/