当前位置:脚本大全 > > 正文

python什么是深拷贝什么是浅拷贝(Python深拷贝与浅拷贝用法实例分析)

时间:2021-10-08 00:50:51类别:脚本大全

python什么是深拷贝什么是浅拷贝

Python深拷贝与浅拷贝用法实例分析

本文实例讲述了python深拷贝与浅拷贝用法。分享给大家供大家参考,具体如下:

1、对象的赋值

对象的赋值实际上是对象之间的引用:当创建一个对象,然后将这个对象赋值给另外一个变量的时候,python并没有拷贝这个对象,而只是拷贝了这个对象的引用。

当对对象做赋值或者是参数传递或者作为返回值的时候,总是传递原始对象的引用,而不是一个副本。如下所示:

在python中将一个变量赋值给另一个变量,传递的是引用.无论是a的内层变化还是外层变化,b都会发生同样的变化.因为b和a指向了同一个引用.类似于c语言中的同一片内存地址.

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • #coding=utf-8
  • a = [1,2,3,['a','b','c']]
  • b = a
  • print('*'*50)
  • print('--- b = a ---')
  • print('a = %s'%a)
  • print('b = %s'%b)
  • a.append(4)
  • print('--- 外层a增加了元素4 ---')
  • print('a = %s'%a)
  • print('b = %s'%b)
  • print('--- 内层增加了元素"d" ---')
  • a[3].append('d')
  • print('a = %s'%a)
  • print('b = %s'%b)
  • 运行结果:

    **************************************************
    --- b = a ---
    a = [1, 2, 3, ['a', 'b', 'c']]
    b = [1, 2, 3, ['a', 'b', 'c']]
    --- 外层a增加了元素4 ---
    a = [1, 2, 3, ['a', 'b', 'c'], 4]
    b = [1, 2, 3, ['a', 'b', 'c'], 4]
    --- 内层增加了元素'd' ---
    a = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
    b = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]

    2、对象的复制

    当你想修改一个对象,而且让原始的对象不受影响的时候,那么就需要使用到对象的复制,对象的复制可以通过三种方法实现:

    a、 使用切片操作进行拷贝 - -slice operation

    (注:切片技术应用于所有的序列,包括:列表、字符串、元祖 ,但切片不能应用于字典。对字典只能使用d.copy()方法或d.deepcopy()方法.)

    b、 使用工厂函数进行拷贝,list / dir / set - -factoryfunction

    c、 copy.copy()–use copymodule

    在复制的时候,使用的是浅拷贝,复制了对象,但是对象中的元素,依然使用引用。

    如下所示:

    a = [1,2,3,['a','b','c']]

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • #coding=utf-8
  • import copy
  • #1.切片操作
  • print('--- 切片操作 ---')
  • b = a[:]
  • print('a = %s\tid(a) = %s'%(a,id(a)))
  • print('b = %s\tid(b) = %s'%(b,id(b)))
  • #2.使用工厂函数
  • print('--- 使用工厂函数 ---')
  • c = list(a)
  • print('a = %s\tid(a) = %s'%(a,id(a)))
  • print('c = %s\tid(c) = %s'%(c,id(c)))
  • #3.copy.copy()
  • print('--- copy.copy() ---')
  • d = copy.copy(a)
  • print('a = %s\tid(a) = %s'%(a,id(a)))
  • print('d = %s\tid(d) = %s'%(d,id(d)))
  • 运行结果:

    --- 切片操作 ---
    a = [1, 2, 3, ['a', 'b', 'c']]  id(a) = 140676047022088
    b = [1, 2, 3, ['a', 'b', 'c']]  id(b) = 140676047021320
    --- 使用工厂函数 ---
    a = [1, 2, 3, ['a', 'b', 'c']]  id(a) = 140676047022088
    c = [1, 2, 3, ['a', 'b', 'c']]  id(c) = 140676047101640
    --- copy.copy() ---
    a = [1, 2, 3, ['a', 'b', 'c']]  id(a) = 140436217635720
    d = [1, 2, 3, ['a', 'b', 'c']]  id(d) = 140436217656904

    在使用浅拷贝的时候,发现引用的id都是相同的,但是字符串的id却发生了变化,是因为在python中,字符串是不可变的,从而在每次进行修改的时候,都是新建一个对象,从而引用发生了变化.

    在不可变类型中,数字和字符串都是不可变类型,从而在每次修改的时候,都是新创建一个对象。

    3、模块

    核心模块:copy

    浅拷贝和深拷贝的操作都可以在copy模块中找到,其实copy模块中只有两个函数可用,copy()进行浅拷贝操作,而deepcopy()进行深拷贝操作.

    如下所示:

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • #coding=utf-8
  • import copy
  • a = [1,2,3,['a','b','c']]
  • #浅拷贝拷贝的是外层即顶级对象,对于内层只拷贝引用
  • #所以在a的外层增加了元素,而c并没有变化.而在a的内层增加元素后,c发生了同样的变化.(回顾b=a)
  • print('*'*50)
  • print('--- c = copy.copy(a)---')
  • c = copy.copy(a)
  • print('a = %s'%a)
  • print('c = %s'%c)
  • a.append(4)
  • print('---外层a增加了元素4---')
  • print('a = %s'%a)
  • print('c = %s'%c)
  • print('---内层增加了元素"d"---')
  • a[3].append('d')
  • print('a = %s'%a)
  • print('c = %s'%c)
  • #深拷贝会递归的拷贝所有内容,将所有的内容都独自拷贝了一份.
  • #故而,无论a的外层还是内层发生变化,都不会影响到d.
  • print('*'*50)
  • print('--- d = copy.deepcopy(a) ---')
  • d = copy.deepcopy(a)
  • print('a = %s'%a)
  • print('d = %s'%d)
  • a.append(5)
  • print('---外层a增加了元素5---')
  • print('a = %s'%a)
  • print('d = %s'%d)
  • print('---内层增加了元素"e"---')
  • a[3].append('e')
  • print('a = %s'%a)
  • print('d = %s'%d)
  • 运行如下:

    **************************************************
    --- c = copy.copy(a)---
    a = [1, 2, 3, ['a', 'b', 'c']]
    c = [1, 2, 3, ['a', 'b', 'c']]
    ---外层a增加了元素4---
    a = [1, 2, 3, ['a', 'b', 'c'], 4]
    c = [1, 2, 3, ['a', 'b', 'c']]
    ---内层增加了元素"d"---
    a = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
    c = [1, 2, 3, ['a', 'b', 'c', 'd']]
    **************************************************
    --- d = copy.deepcopy(a) ---
    a = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
    d = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
    ---外层a增加了元素5---
    a = [1, 2, 3, ['a', 'b', 'c', 'd'], 4, 5]
    d = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]
    ---内层增加了元素"e"---
    a = [1, 2, 3, ['a', 'b', 'c', 'd', 'e'], 4, 5]
    d = [1, 2, 3, ['a', 'b', 'c', 'd'], 4]

    4、拷贝的警告

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

    第二:如果元组变量只包含原子类型对象,那么深拷贝将不会进行。

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • #coding=utf-8
  • import copy
  • a = (1,2,3)
  • print('*'*50)
  • print('--- c = copy.copy(a)---')
  • c = copy.copy(a)
  • print(a,id(a))
  • print(c,id(c))
  • print('*'*50)
  • print('--- d = copy.deepcopy(a) ---')
  • d = copy.deepcopy(a)
  • print(a,id(a))
  • print(d,id(c))
  • 运行如下:

    **************************************************
    --- c = copy.copy(a)---
    (1, 2, 3) 140394676674992
    (1, 2, 3) 140394676674992
    **************************************************
    --- d = copy.deepcopy(a) ---
    (1, 2, 3) 140394676674992
    (1, 2, 3) 140394676674992

    可见:

    对于可变类型来说,深拷贝和浅拷贝是不同的.

    而对于不可变类型来说,深拷贝和浅拷贝的结果相同!

    希望本文所述对大家python程序设计有所帮助。

    原文链接:https://blog.csdn.net/xuezhangjun0121/article/details/76945033

    上一篇下一篇

    猜您喜欢

    热门推荐