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

时间:2010-07-15 07:41:32

标签: python copy

好的......这可能是一个愚蠢的问题......但我现在没有找到答案!

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

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

>>> 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): ...)???

3 个答案:

答案 0 :(得分:5)

你可以这样做:

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

这将起作用,因为deepcopy可以避免递归。来自python docs

  

deepcopy()函数通过以下方式避免了这些问题:   保留当前复制过程中已复制的对象的“备忘录”字典;和   让用户定义的类覆盖复制操作或复制的组件集。

答案 1 :(得分:3)

如果您没有属性& c,则所有状态都在__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 :(得分:2)

我想以下列方式做到这一点 - 试试吧:

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

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