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()进行深拷贝
    * 对于非容器类型(如数字、字符串、和其他'原子'类型的对象)没有被拷贝一说
    * 如果元祖变量只包含原子类型对象,则不能深拷贝
    """
    
  • 相关阅读:
    nignx 配置https
    开发插件
    pdf 转word 网站
    github 镜像站点
    apk 托管
    系统引导原理以及过程
    网络维护-路由与路由的链接
    linux 常用命令
    Linux netsat 命令
    Oracle登录 ORA-01033: ORACLE正在初始化或关闭的解决方法
  • 原文地址:https://www.cnblogs.com/sandy-t/p/8203647.html
Copyright © 2011-2022 走看看