python中浅拷贝与深拷贝

参考链接
1. 引用 https://blog.csdn.net/qq_38556217/article/details/103002827
2. Python中变量在内存的存储与地址变化详解(深浅拷贝,值/引用传递、可变不可变数据类型)
3. python深拷贝和浅拷贝的区别

首先深拷贝和浅拷贝都是对象的拷贝,都会生成一个看起来相同的对象,他们本质的区别是拷贝出来的对象的地址是否和原对象一样,也就是地址的复制还是值的复制的区别

在这里插入图片描述

一、可变对象与不可变对象

  1. 可变对象:当有需要改变对象的值的时候,这个对象的id不发生变化(不超过存储空间的情况)。可变类型数据:列表、集合、字典、对象
  2. 不可变对象:当有需要改变对象的值的时候,这个对象的id会发生变化。不可变类型数据:数值、字符串、布尔、元组
    3.id()获取对象的内存地址
  3. python地址存储特殊性,使用固定内存地址存储数据如下:
    -5到256的整数、True和False、由字母、数字、下滑线组成的字符串

二、对可变对此的操作是否新建对象?

这里以列表为例,实验对列表的操作,是否改变了列表对象,及id(列表对象)是否发生了变化。

2.1 不改变id(列表对象)的操作

  • append()方法
  • += 连接列表
  • 删除某个元素 del l[1]
  • 改变某个元素的值 l[2]=10

2.2 改变id(列表对象)的操作

* 切片操作,`a[:2]`,及全部复制`a[:]`
* 连接列表 `a = a + [...]`

三、赋值、浅拷贝与深拷贝

Python 中赋值语句不复制对象,而是在目标和对象之间创建绑定 (bindings) 关系。
在这里插入图片描述

3.1 赋值操作=

相当于复制一个引用,指向同一个内存地址。改变其中一个变量的值,

  • 如果是可变对象,其余的也会跟着变。它们之间的id值相同
    在这里插入图片描述
  • 如果是不可变对象,改变其中一个变量的值相当于新建一个对象,它们之间的id值不同
    在这里插入图片描述

3.2 浅拷贝

浅拷贝会新建一个对象,拷贝对象与元对象的变化间有无关联,要看元对象中的元素类型
在这里插入图片描述

  1. 被拷贝的对象中是否包含可变对象
  • 不包含。拷贝后对象变化与原对象间没有关系
    在这里插入图片描述
  • 包含。可变对象的变化会同时发生在原对象和拷贝对象中。
    在这里插入图片描述

拷贝的对象中,包含可变对象时,新对象中保存的是可变对象的地址。

3.3 深拷贝

拷贝后,拷贝后对象变化与原对象间没有关系
在这里插入图片描述

在这里插入图片描述

浅拷贝与深拷贝的区别,总的来说就是拷贝一层和多层的区别
深拷贝操作通常存在两个问题, 而浅拷贝操作并不存在这些问题:

  • 递归对象 (直接或间接包含对自身引用的复合对象) 可能会导致递归循环。
  • 由于深拷贝会复制所有内容,因此可能会过多复制(例如本应该在副本之间共享的数据)。

四、引用传递与值传递

可变对象为引用传递,不可变对象为值传递。(函数传值)

1,值传递: 简单来说 对于函数输入的参数对象,函数执行中首先生成对象的一个副本,并在执行过程中对副本进行操作。执行结束后对象不发生改变
即在堆栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。(被调函数新开辟内存空间存放的是实参的副本值)

值传递不会改变原来函数的值,

def Change(b):
    b += 2   传递进来的为不可变对象,为值传递  相当于相同值的一个副本
    print(id(b)) 
    print (b)
    return

a = 2
print(id(a)) 
Change(a)
print (a)
print(id(a)) 

输出为

140724617470832    a本来地址
140724617470896    值传递b的地址
4                                在函数中为4
2                                a本身还是2
140724617470832    a地址也没有改变

4.2. 引用传递

当传递列表或者字典时,如果改变引用的值,就修改了原始的对象。(被调函数新开辟内存空间存放的是实参的地址)

def Change(str1):
    str1[1] ="changed "   此处修改就是直接修改string的值
    return

string = ['hello world',2,3]
print (string)
Change(string)       
print (string)

在这里插入图片描述

函数的实参使用可变类型数据时,在函数内部对形参进行数据操作,实参将发生改变
函数的实参使用不可变类型数据时,在函数内部对形参进行数据操作,实参将不会发生改变

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值