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

4 投票
3 回答
3426 浏览
提问于 2025-04-16 01:20

好的……这可能是个傻问题……但我现在找不到答案!

我需要复制一个对象,想要把所有的属性都复制过来,但有一两个属性我想要完全控制它们的复制方式。

这里是对象的标准复制行为:

>>> 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 个回答

2

我想用以下方式来实现这个 - 试试看:

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

    def __copy__(self):
        obj_copy = copy.deepcopy(self)
        return obj_copy 
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
5

你可以这样做:

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

这样做是有效的,因为 deepcopy 可以避免递归的问题。根据 Python 文档 的说明:

deepcopy() 函数通过以下方式避免这些问题: 1. 保持一个“备忘录”字典,用来记录在当前复制过程中已经复制过的对象; 2. 允许用户自定义的类重写复制操作或被复制的组件集合。

撰写回答