Python复制:如何继承默认的复制行为?

4

好的...也许这是一个愚蠢的问题...但我现在找不到答案!

我需要实现一个对象的复制,我希望所有的属性都被复制,除了一两个我想要完全控制复制的属性。

以下是对象的标准复制行为:

>>> class test(object):
...     def __init__(self, arg):
...         self._a = arg
... 
>>> t = test(123999)
>>> t._a
123999
>>> tc = copy.copy(t)
>>> tc._a
123999

这基本上意味着所有属性都被复制。我想要做的是以以下方式重用此行为:

>>> class test(object):
...     def __init__(self, arga, argb):
...         self._a = arga
...         self._b = argb
...
...     def __copy__(self):
...         obj_copy = copy.copy(self) #NOT POSSIBLE OF COURSE => infinite recursion
...         obj_copy._b = my_operation(obj_copy._b)
...         return obj_copy

我希望你能理解我的意思:我想要重用对象复制行为,但是插入自己的操作。有没有一种干净的方法来做到这一点(而不必做for attr_name in dir(self): ...)?

如果你是相对新手的Python程序员,并且认为你需要复制一个对象,除非你可以解释清楚为什么复制能做一些对象本身不能做的事情,否则你很可能是错误的。 - msw
我已经有一段时间没有写Python了...相信我,这次我知道我必须要复制! - sebpiq
3个回答

5
您可以这样操作:

只需要执行以下步骤:

def __copy__(self):
    clone = copy.deepcopy(self)
    clone._b = some_op(clone._b)
    return clone

这将有效,因为deepcopy避免了递归。根据Python文档
深度复制函数通过以下方式避免这些问题: - 在当前复制过程中保留一个“备忘录”字典已经复制的对象; - 让用户定义的类覆盖复制操作或要复制的组件集合。

所有的回答都很好,但实际上这是最简单的...谢谢! - sebpiq

3
如果您没有属性和方法等内容,所有状态都在__dict__中,因此...:
...     def __copy__(self):
...         obj_copy = object.__new__(type(self))
...         obj_copy.__dict__ = self.__dict__.copy()
...         obj_copy._b = my_operation(obj_copy._b)
...         return obj_copy

2
我希望你能尝试以下方式来完成这个任务:

尝试如下步骤:

import copy
class test(object):
    def __init__(self, **args):
        self.args = args

    def __copy__(self):
        obj_copy = copy.deepcopy(self)
        return obj_copy 

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