zoukankan      html  css  js  c++  java
  • 一入python深似海--浅拷贝与深拷贝

    python中有一个模块copy,deepcopy函数用于深拷贝,copy函数用于浅拷贝。

    要理解浅拷贝,必须先弄清楚python中的引用。

    引用

    Python中一切都是对象,变量中存放的是对象的引用

    这是一个普遍的法则。能够说 Python 没有赋值,仅仅有引用

    如。a=1,变量a仅仅是整数对象1的引用。


    可变对象与不可变对象及其引用

    一、不可变对象

    不可变对象包含:数字,字符串,元组。
    因为Python中的变量存放的是对象引用。所以对于不可变对象而言,虽然对象本身不可变。但变量的对象引用是可变的。运用这种机制,有时候会让人产生糊涂,似乎可变对象变化了。如以下的代码:
    i=73
    i+=2
    这里的‘=’表示引用。


    从上面得知。不可变的对象的特征没有变,依旧是不可变对象,变的仅仅是创建了新对象,改变了变量的对象引用。

    二、可变对象

    可变对象包含:列表、字典
    其对象的内容是能够变化的。

    当对象的内容发生变化时。变量的对象引用是不会变化的。如以下的样例。

    m=[5,9]
    m+=[6]
    列表m的每一个元素均是对象的引用。对象的生成。涉及到相应机制。如整形对象分为大整数对象和小整数对象,生成机制不同,这里不作具体阐述。



    三、函数的參数传递

    函数的參数传递。本质上传递的是引用。

    拷贝

    (1)没有限制条件的分片表达式(L[:])可以复制序列,但此法仅仅能浅层复制

    (2)字典 copy 方法。D.copy() 可以复制字典,但此法仅仅能浅层复制

    (3)有些内置函数。比如 list,可以生成拷贝 list(L)

    (4)copy 标准库模块可以生成完整拷贝:deepcopy,递归 copy


    浅拷贝

    浅拷贝由copy模块中的copy()函数实现。简单地说,copy.copy 浅拷贝 仅仅拷贝父对象,不会拷贝对象的内部的可变子对象

    详细点说就是。浅拷贝是指拷贝的仅仅是原对象元素的引用,换句话说,浅拷贝产生的对象本身是新的,可是它的内容不是新的,仅仅是对原子对象的一个引用


    import copy
    aList=[[1,2],3,4]
    bList=copy.copy(aList)
    print aList
    print bList
    
    print id(aList)
    print id(bList)
    
    aList[0][0]=5
    
    print aList
    print bList

    由id(aList)不等于id(bList),表明浅拷贝产生的对象本身是新的。可是它的子对象(即,那个列表)是对原子对象的一个引用。

    那么3,4两个元素呢?这就要讲讲python中的可变对象和不可变对象的引用了。



    可是有点须要特别提醒的,假设对象本身是不可变的,那么浅拷贝时也是引用。

    见这个样例:

    import copy
    aList=[[1,2],3,4]
    bList=copy.copy(aList)
    print aList
    print bList
    
    print id(aList[1])
    print id(bList[1])
    
    aList[2]=5#变量的对象引用改变了而已
    aList[0]=[0,1,1]#变量的对象引用改变了而已
    
    print aList
    print bList

    总结,即浅拷贝产生的对象本身是新的。可是它的内容不是新的,仅仅是对原子对象的一个引用

    深拷贝

    浅拷贝由copy模块中的deepcopy()函数实现,简单地说。深拷贝 拷贝对象及其子对象。

    一个样例展示引用、深拷贝与浅拷贝的不同。

    import copy
    aList=[[1,2],3,4]
    bList=aList
    cList=copy.copy(aList)
    dList=copy.deepcopy(aList)
    print aList
    print bList
    print cList
    print dList
    print id(aList)
    print id(bList)
    print id(cList)
    print id(dList)
    aList.append(5)
    aList[0].append('hello')
    
    print aList
    print bList
    print cList
    print dList



    事实上我认为记住这一点即可,浅拷贝产生的对象本身是新的,可是它的内容不是新的。仅仅是对原子对象的一个引用。关键是要理解python中引用的含义。


  • 相关阅读:
    Hadoop之MapReduce
    Hadoop之序列化
    Hadoop之mapreduce 实例五
    Hadoop之hive和hadoop的交互流程
    protel总结1
    将正数十进制转换为2~16进制数
    基于verilog分频器总结
    MATLAB设计FIR滤波器
    centos7+hadoop完全分布式集群搭建
    Linux下常用配置文件
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5178274.html
Copyright © 2011-2022 走看看