Python:浅拷贝和深拷贝构造函数的实现

11

在C++中,由于存在指针的概念,实现复制构造函数(或重载赋值运算符)通常很容易。然而,我对如何在Python中实现浅拷贝和深拷贝感到困惑。

我知道其中一个库中有特殊命令,但它们不适用于您自己编写的类。那么,有哪些常见的实现方法呢?

注:如果能够展示一些基本数据结构(如链表或树)的过程,将不胜感激。

编辑:谢谢,它们起作用了,这是我的语法错误。 我非常感兴趣地想要用__copy__()__deep_copy()__重写这些函数。例如,如果不知道数据结构中包含哪种类型的信息,该如何进行深拷贝?


5
您的意思是自己设计的类无法使用库吗? copy.copycopy.deepcopy 有什么问题吗? - David Robinson
1个回答

26

Python的copy模块可以重用pickle模块接口,以便让类自定义复制行为。

对于自定义类的实例,默认情况下会创建一个新的空类,交换__class__属性,然后对于浅层复制,只需使用原始值更新副本上的__dict__。深度复制递归遍历__dict__

否则,您可以指定一个__getstate__()方法来返回内部状态。这可以是您的类__setstate__()再次接受的任何结构。

您还可以指定__copy__()和/或__deepcopy__()方法来控制复制行为。这些方法被期望完成所有复制工作,__deepcopy__()方法传递一个备忘录映射表以传递给递归deepcopy()调用。

例如:

from copy import deepcopy

class Foo(object):
    def __init__(self, bar):
        self.bar = bar
        self.spam = expression + that * generates - ham   # calculated

    def __copy__(self):
        # self.spam is to be ignored, it is calculated anew for the copy
        # create a new copy of ourselves *reusing* self.bar
        return type(self)(self.bar)

    def __deepcopy__(self, memo):
        # self.spam is to be ignored, it is calculated anew for the copy
        # create a new copy of ourselves with a deep copy of self.bar
        # pass on the memo mapping to recursive calls to copy.deepcopy
        return type(self)(deepcopy(self.bar, memo))

这个例子定义了自定义的复制钩子,以防止self.spam也被复制,因为一个新实例会重新计算它。

我对最后的解决方案非常感兴趣。如果不知道类型,如何从一个值中复制另一个值?我应该为所有类型编写代码吗?还是有更简单的解决方案? - Kudayar Pirimbaev
1
@KudayarPirimbaev:你可以将包含的值委托给copy.deepcopy递归调用,它会处理不同类型。 - Martijn Pieters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接