在Python类中实现克隆方法的适当惯用方式是什么?

5

如何在Python中以惯用方式正确实现clone方法?请参见:

def clone(self):
    """
    Return a clone of this class
    """
clone的原因是为了从使用角度构造相同的类实例,因此可以更改副本的内部状态而不影响原始对象。
具体来说:构造函数可能会初始化私有字段,这些字段可以是基本类型或复杂类型。
def __init__(self, initial = None, width = DEFAULT_SIZE, height = DEFAULT_SIZE):
    self._width = width
    self._height = height
    self._matrix = ...complex code, list of list...

对于基本类型 - 没有什么难度。复杂类型该如何处理?

如果复杂类型是内置的,例如tuple, set, dict - 那么就可以使用copy.copy / copy.deepcopy包,但我不确定它的常规用法。

对于外部类的复杂类型,我不知道该怎么做。

(1) 是否有任何辅助工具使复制变得容易? 或者我可以依靠哪些约定?

当我复制对象时,我看不到使用提供的构造函数的理由,因为我已经知道所有内部协议并且能够私下操纵内部状态?

(2) 我如何实例化相同类型的对象而不使用构造函数?

更新 我正在参加Coursera的计算原理课程,并实现了一些被教学内容隐藏的类(为了评分)。

他们在提供的"接口"中使用clone。我对Python类没有经验,所以请问在这种情况下应该如何处理?


@kindall 官方文档说:copy.deepcopy 允许用户定义的类覆盖复制操作或要复制的组件集。这个API应该由类来实现吗? - gavenkoa
2
为了让一个类定义自己的复制实现,它可以定义特殊方法__copy__()__deepcopy__() - Dan D.
是的,没错。实现他们的API,这样用户就可以使用标准模块来进行复制。 - kindall
1个回答

5
要么实现__deepcopy__(和/或__copy__)来直接支持 copy 模块 API,要么使用copyreg注册pickle函数;如果未定义__deepcopy__,则copy.deepcopy将使用copyreg注册的方法来实现深度复制。

请注意许多Python类型(例如dictlist等)还提供名为copy的方法来执行浅拷贝。可以通过将一个名称分配给另一个名称来轻松支持这两种惯用法,例如:

class Foo:
    def copy(self):
        ... do stuff to make a copy ...
        return newcopy
    __copy__ = copy  # Now works with copy.copy too

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