说说Python中的浅拷贝和深拷贝

浅复制通常只复制对象本身,而深复制不仅会复制对象,还会复制对象所关联的对象。深复制可能会遇到两个问题:一个是一个对象,如果直接或引用的引用了自身,会导致无休止的深拷贝操作;二是深拷贝可能对什么设计为多个对象共享的数据也进行拷贝。Python通过模块中copycopydeepcopy函数来实现浅拷贝和深拷贝操作,其中deepcopy通过memo字典来保存已经复制过的对象,从而避免前述的自引用递归问题;此外,可以通过copyreg模块的pickle函数来定制指定类型对象的复制行为。

deepcopy函数的本质其实就是对象的一次序列化和一次返回序列化,面试题中还考过用自定义函数实现对象的深拷贝操作,显然我们可以使用pickle模块的dumpsloads实现,代码如下所示。

import pickle

my_deep_copy = lambda obj: pickle.loads(pickle.dumps(obj))

列表的切片操作[:]实际上实现了列表对象的浅拷贝,而字典的copy方法可以实现字典对象的浅拷贝。对象拷贝其实是更快捷的对象创建的方式。在Python中,通过构造器创建属于两个的对象阶段构造,首先是分配内存空间,然后是初始化。在对象时,我们也可以基于“原型”对象来创建新对象,通过对原型对象创建的复制(复制内存)就完成了对象的创建和初始化,这样的做法比较多,这就是原生设计模式中的原型模式。在Python中,我们可以高效地通过元类的方式来实现原型模式,代码如下所示。

import copy


class PrototypeMeta(type):
    """实现原型模式的元类"""

    def __init__(cls, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 为对象绑定clone方法来实现对象拷贝
        cls.clone = lambda self, is_deep=True: \
            copy.deepcopy(self) if is_deep else copy.copy(self)


class Person(metaclass=PrototypeMeta):
    pass


p1 = Person()
p2 = p1.clone()                 # 深拷贝
p3 = p1.clone(is_deep=False)    # 浅拷贝

你可能感兴趣的:(python,java,开发语言)