copy()和deepcopy()之间的Python函数

时间:2014-12-06 19:37:03

标签: python

我的回复可被视为this post的后续行动。

我有一个包含对象列表的字典。我想在copy模块中的deepcopycopy函数之间使用一些函数。我想要一些在内置Python结构和基元(整数,集合,字符串,列表等)上执行深层复制的东西,但不能生成用户自制对象的深层副本(或非原始对象) -aggregate对象)。

似乎我可能需要修改对象的__deepcopy__方法,但我不太确定如何正确执行此操作。如果我想在将来的脚本中制作对象的深层副本,那么不修改对象的__deepcopy__方法的解决方案也是可取的。

假设这是我的Python文件的顶部:

import copy

class Obj():
    def __init__(self,i):
        self.i = i
        pass

d = {0:Obj(5),1:[Obj(6)],2:[]}
d2 = copy.deepcopy(d)

作为示例,我将在下面列出一些代码片段,以及实际输出和所需的输出。

Snippet 1

d[1][0].i=7
print "d[1][0].i:",d[1][0].i,"d2[1][0].i:",d2[1][0].i
  • 实际输出:d[1][0].i: 7 d2[1][0].i: 6
  • 期望输出d[1][0].i: 7 d2[1][0].i: 7

Snippet 2

d[0].i = 6
print "d[0].i:",d[0].i,"d2[0].i:",d2[0].i
  • 实际输出:d[0].i: 6 d2[0].i: 5
  • 期望输出d[0].i: 6 d2[0].i: 6

2 个答案:

答案 0 :(得分:1)

您可以直接从文档中获取:

import copy

class Obj:
    def __init__(self, i):
        self.i = i

    def __deepcopy__(self, memo):
        return self

您的上一个示例似乎不对,因为d3d的浅层副本,因此2索引的列表应保持相同的参考。

要允许深度复制作为选项,您可以在对象中设置一些属性,并在__deepcopy__中检查该属性。

答案 1 :(得分:0)

您可以看到(纯python)deepcopycopy方法是如何制作的here。您可以尝试为特定对象制作更简单的对象,或尝试修改“原始”。

您还可以修改对象的__deepcopy__方法,只返回self,但这可能会影响他们的行为 - 当然,如果您希望稍后deepcopy,但是如果你使用一些外部库,例如调试器或GUI。