zoukankan      html  css  js  c++  java
  • python的深拷贝和浅拷贝

    # 对象赋值
    a = 'hello world'
    b = a
    print('a:',a,', b:',b)
    # a: hello world , b: hello world
    print(id(a)==id(b))
    # True
    a = 'Hello World'
    print('a:',a,', b:',b)
    # Hello World , b: hello world
    print(id(a)==id(b))
    # False
    
    
    a = 1
    b = a
    print('a:',a,', b:',b)
    # a: 1 , b: 1
    print(id(a)==id(b))
    # True
    a = 2
    print('a:',a,', b:',b)
    # a: 2 , b: 1
    print(id(a)==id(b))
    # False
    
    
    a = ['x','y',[1,2,3]]
    b = a
    print('a:',a,', b:',b)
    # a: ['x', 'y', [1, 2, 3]] , b: ['x', 'y', [1, 2, 3]]
    print(id(a)==id(b))
    # True
    a.append('hello')
    print('a:',a,', b:',b)
    # a: ['x', 'y', [1, 2, 3], 'hello'] , b: ['x', 'y', [1, 2, 3], 'hello']
    print(id(a)==id(b))
    # True
    a[2].append(4)
    print('a:',a,', b:',b)
    # a: ['x', 'y', [1, 2, 3], 'hello'] , b: ['x', 'y', [1, 2, 3], 'hello']
    print(id(a)==id(b))
    # True
    
    """
    所以在python中,对象的赋值都是进行对象引用(内存地址)传递,只要a的内存地址没有变化,a和b的内容都会始终一样。
    """
    
    a = ['x','y',[1,2,3]]
    b = a[:]
    print('a:',a,', b:',b)
    # a: ['x', 'y', [1, 2, 3]] , b: ['x', 'y', [1, 2, 3]]
    print(id(a)==id(b))
    # False
    print([id(i) for i in a])
    # [2059734973832, 2059735268016, 2059766662792]
    print([id(i) for i in b])
    # [2059734973832, 2059735268016, 2059766662792]
    
    a.append('hello')
    print('a:',a,', b:',b)
    # a: ['x', 'y', [1, 2, 3], 'hello'] , b: ['x', 'y', [1, 2, 3]]
    print(id(a)==id(b))
    # False
    a[2].append(4)
    print('a:',a,', b:',b)
    # a: ['x', 'y', [1, 2, 3, 4], 'hello'] , b: ['x', 'y', [1, 2, 3, 4]]
    print(id(a)==id(b))
    # False
    
    print('浅拷贝')
    # 浅拷贝
    import copy
    a = ['x','y',[1,2,3,[4,5,6]]]
    d = copy.copy(a)
    print('a:',a,', b:',b)
    # a: ['x', 'y', [1, 2, 3, [4, 5, 6]]] , b: ['x', 'y', [1, 2, 3, 4]]
    print(id(a)==id(b))
    # False
    print([id(i) for i in a])
    # [2640575102344, 2640603314864, 2640606922568]
    print([id(i) for i in b])
    # [2640575102344, 2640603314864, 2640606922824]
    a[2].append(4)
    print('a:',a,', b:',b)
    # a: ['x', 'y', [1, 2, 3, [4, 5, 6], 4]] , b: ['x', 'y', [1, 2, 3, 4]]
    tmp_list_a = a[2]
    print(id(tmp_list_a))
    # 2640606922568
    print([id(i) for i in tmp_list_a])
    # [1434892752, 1434892784, 1434892816, 2640606922632, 1434892848]
    tmp_list_b = b[2]
    print(id(tmp_list_b))
    # 2640606922824
    print([id(i) for i in tmp_list_b])
    # [1434892752, 1434892784, 1434892816, 1434892848]
    
    """
    所以在python(python3.6)中浅拷贝会将不可变元素的地址直接拷贝,而可变对象如list会用新的地址指向原list内存区域,相当于两个不同的指针指向同样的内存区。
    """
    
    # 深拷贝
    
    import copy
    a = ['x','y',[1,2,3,[4,5,6]]]
    b = copy.deepcopy(a)
    print('a:',a,', b:',b)
    # a: ['x', 'y', [1, 2, 3, [4, 5, 6]]] , b: ['x', 'y', [1, 2, 3, [4, 5, 6]]]
    print(id(a)==id(b))
    # False
    print([id(i) for i in a])
    # [2460486303112, 2460486597296, 2460490204808]
    print([id(i) for i in b])
    # [2460486303112, 2460486597296, 2460490204616]
    tmp_list_a = a[2]
    print(id(tmp_list_a))
    # 2460490204808
    print([id(i) for i in tmp_list_a])
    # [1434892752, 1434892784, 1434892816, 2460490204872]
    tmp_list_b = b[2]
    print(id(tmp_list_b))
    # 2460490204616
    print([id(i) for i in tmp_list_b])
    # [1434892752, 1434892784, 1434892816, 2460490204552]
    
    """
    深拷贝,就是会递归的进行拷贝,直到查找到原子类型。
    """
    
    # 补充:
    """
    对于拷贝有一些特殊情况:
        对于非容器类型(如数字、字符串、和其他'原子'类型的对象)没有拷贝这一说
    也就是说,对于这些类型,如果元祖变量只包含原子类型对象,则不能深拷贝。
     如下例子:
    """
    a = (1,'x')
    b = copy.copy(a)
    print(id(a)==id(b))   #没有拷贝
    # True
    b = copy.deepcopy(a)
    print(id(a)==id(b))   #没有拷贝
    # True
    
    a = (1,'x',[2])
    b = copy.copy(a)
    print(id(a)==id(b))   #没有拷贝
    # True
    b = copy.deepcopy(a)
    print(id(a)==id(b))   #拷贝
    # False
    
    # 总结
    """
    * Python中对象的赋值都是进行对象引用(内存地址)传递
    * 使用copy.copy(),可以进行对象的浅拷贝,它复制了对象,但对于对象中的元素,依然使用原始的引用.
    * 如果需要复制一个容器对象,以及它里面的所有元素(包含元素的子元素),可以使用copy.deepcopy()进行深拷贝
    * 对于非容器类型(如数字、字符串、和其他'原子'类型的对象)没有被拷贝一说
    * 如果元祖变量只包含原子类型对象,则不能深拷贝
    """
    
  • 相关阅读:
    在Linux上使用C语言编程获取IPv4地址及子网掩码
    使用gdb进行写操作
    [中英对照]The Art Of Reporting Bugs | 报bug的艺术
    [中英对照]Introduction to Remote Direct Memory Access (RDMA) | RDMA概述
    Intel万兆网卡背靠背连接ping不通那点事儿
    [中英对照]The sysfs Filesystem | sysfs文件系统
    图说单播,组播,广播,选播和地域播
    Ubuntu双网卡不双待攻略
    反汇编容易反编译难
    PHP之路——微信公众号授权获取用户信息
  • 原文地址:https://www.cnblogs.com/sandy-t/p/8203647.html
Copyright © 2011-2022 走看看