• python中的浅拷贝和深拷贝


    1、赋值语句

    1 a = 'abc'
    2 b = a
    3 print id(a)
    4 print id(b)
    5 
    6 # id(a):29283464
    7 # id(b):29283464

    通过简单的复制,我们可以看到,a b其实是一个对象。

    对象赋值实际上是简单的对象引用,也就是说,当你创建了一个对象,然后把它赋值给另一个变量时,python并没有拷贝这个对象,而是拷贝了这个对象的引用。

    2、浅拷贝

    序列类型的对象默认类型拷贝是浅拷贝,通过以下几种方式实施:

      (1) 完全切片操作[:]

      (2) 利用工厂函数,例如list() 、dict()等

      (3) 使用copy模块中的copy函数

    创建一个列表对象,然后分别用切片操作和工厂方法拷贝对象,然后使用id()内建函数来显示每个对象的标识符。

    s = ['abc',['def',1]]
    a = s[:]
    b= list(s)
    print [id(x) for x in s,a,b]
    #[29262792.29238576,28957272]
    

    可以看到创建了三个不同的列表对象。在对对象的每一个元素进行操作:

    a[0] = 'a'
    b[0] = 'b'
    print a,b
    # (['a',['def',1]],['b',['def',1]])
    
    a[1][1] = 0
    print a,b
    # (['a',['def',0]],['b',['def',0]])

    我们可以看到,当执行a[1][1] = 0时,b[1][1]也跟着变为0。这是因为我们仅仅做了一个浅拷贝,对一个对象进行浅拷贝其实是新创建了一个类型跟原对象一样,它的内容元素是原来对象元素的引用,换句话说,这个拷贝的对象是新的,但他的内容还是原来的。这就是浅拷贝。

    但是我们看到a的第一个元素,即字符串被赋值后,并没有影响b的。这是因为在这个对象中,第一个字符串类型是不可变的,第二个列表对象是可变的。正因为如此,当进行浅拷贝时,字符串被显式的拷贝,并创建了一个新的字符串对象,而列表元素只是把它的引用复制了,并不是他的成员。

    #改变前
    print [id(x) for x in a]
    #[29563284,27843874]
    print [id(x) for x in b]
    #[29563284,27843874]
    
    #改变后
    print [id(x) for x in a]
    #[23464734,27843874]
    print [id(x) for x in b]
    #[29884656,27843874]

    3 深拷贝

    根据上面的例子,如果我们想要在改变a时不影响到b,要得到一个完全拷贝或者说深拷贝(一个新的容器对象,包含原有对象元素全新拷贝的引用),就需要copy.deepcopy()函数。

    import copy
    s = ['abc',['def',1]]
    a = copy.deepcopy(s)
    b = copy.deepcopy(s)
    print [id(x) for x in s,a,b]
    #[29278336,29262792,29238576]

    a[0] = 'a' b[0] = 'b' a[1][1] = 0 print a,b #(['a',['def',0]],['b',['def',1]])

    需要注意的是:第一,非容器类型(比如数字、字符串和其他“原子”类型的对象,像代码、类型和xrange对象等)没有拷贝一说,浅拷贝是用完全切片操作来完成的。

           第二:如果元组变量只包含原子类型对象,对他的拷贝将不会进行,即使使用深拷贝操作也只能得到一个浅拷贝。

  • 相关阅读:
    Mybatis详解(二)
    Mybatis详解(一)
    Java集合
    Java基础之IO
    Java异常知识点!
    HTTP状态码
    ajax传字符串时出现乱码问题的解决
    Json 文件 : 出现 Expected value at 1:0 问题的解决
    java @XmlTransient与@Transient区别
    文件的上传和回显
  • 原文地址:https://www.cnblogs.com/mzct123/p/6033959.html
Copyright © 2020-2023  润新知