python深浅拷贝——copy库

文章目录


Python中的赋值表达式并不会赋值对象,只是创建目标和对象之间的绑定。本模块提供通用浅和深拷贝操作。

浅拷贝和深拷贝只和复合对象有关:

  • 浅拷贝构造一个新的复合对象,然后(在可能的范围内)向其中插入对原始对象中的对象的引用
  • 深拷贝构造一个新的复合对象,然后递归地向其中插入对原始对象的复制(不同于原对象)。

两个常见于深拷贝而不存在于浅拷贝的问题:

  • 递归对象(那些直接或间接包含自身引用的复合对象)可能导致递归循环。
  • 因为深拷贝复制任何内容,它可能复制太多内容,而这些内容可能用于在复制中共享。

copy.deepcopy()函数避免了这些问题,通过:

  • 维护一个字典memo,这个字典保存了之前复制过的对象。
  • 让用户自定义类重写复制操作或复制组件集。

本模块可复制的内容和pickle模块所定义兼容。

字典的浅拷贝可通过dict.copy(),而列表的浅拷贝可通过切片copied_list = original_list[:]

类可通过使用控制序列化相同的接口控制复制。如__reduce_ex__(version)__reduce__()

类可以通过实现复制协议定义自身复制实现。__copy__()实现浅拷贝,__deepcopy__()实现深拷贝。

浅拷贝

浅拷贝的实现:

  • 对于常见的不可变类型(如int等)和可变类型(如list等)等,通过类型从_copy_dispatch映射中获取复制函数进行浅拷贝操作。
  • 其他类型如自定义的类,如果实现了__copy__()则调用该方法进行浅拷贝;如果copyreg模块中的dispatch_table映射有该类型的复制函数,则调用该函数进行浅拷贝;如果实现了序列化协议(如__reduce_ex__()__reduce__())则调用该方法进行浅拷贝。
import types
import weakref
from copyreg import dispatch_table

def copy(x):
    """Shallow copy operation on arbitrary Python objects.

    See the module's __doc__ string for more info.
    """

    cls = type(x)

    copier = _copy_dispatch.get(cls)
    # 如果是常见类型,如不可变类型int,可变类型list,
    # 直接通过复制函数进行拷贝操作。
    if copier:
        return copier(x)

    if issubclass(cls, type):
        # treat it as a regular class:
        return _copy_immutable(x)

    # 如果该对象实现浅拷贝协议,则通过浅拷贝
    # 特殊方法实现拷贝操作。
    copier = getattr(cls, "__copy__", None)
    if copier is not None:
        return copier(x)

    # 从copyreg获取对应类型的复制函数
    reductor = dispatch_table.get(cls)
    if reductor is not None:
        rv = reductor(x)
    else:
        # 从__reduce_ex__中获取对应的压缩方法,
        # 这个是序列化协议的内容,但可用于拷贝操作,
        # 继承object的类默认实现该方法
        reductor = getattr(x, "__reduce_ex__", None)
        if reductor is not None:
            rv = reductor(4)
        else:
            reductor = getattr(x, "__reduce__", None)
            if reductor:
                rv = reductor()
            else:
                raise Error("un(shallow)copyable object of type %s" % cls)

    if isinstance(rv, str):
        return x
    # _reconstruct函数在浅拷贝中主要是通过
    # 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值