python函数方法里面用浅复制深复制_父对象、子对象以及直接赋值、浅拷贝(copy)、深拷贝(deepcopy)...

python中数据存储和C中区别:

Python中:

a=2

b=a

a=3

该过程中的内存储存方式为:

1、先再内存中开栈存储2这个数据的空间

2、a指向数据为2的内存空间地址

3、b=a 此时b指向2的内存空间的地址

4、a=3 内存中开栈存储3这个数据的空间

5、此时a=3中,a重新指向数据为3的内存地址

总结:Python是动态语言,变量只是对象的引用,不同于C中将值赋给变量(j将值存放到变量代表的内存空间中),动态语言中,变量只是对象的引用,即对象本身有自己的内存空间,变量只是指向了该内存空间。

python中,进行函数參数传递或者返回值时,假设是一般的变量,会拷贝传递。假设是列表或字典则是引用传递。

直接赋值:其实就是对象的引用(别名)

(变量、列表、字典、元祖、集合等)直接赋值都只是原来对象的引用,赋值后改变原来对象,新对象也会发生改变。

##

# 数据

##

a = 3//a指向数据3的内存空间

b = a//b也指向数据3的内存空间

a = 4//a指向数据4的内存空间,b = 3

a = 4之后,b依旧指向数据3的内存空间

##

# 列表,第一种变值

#

##

list_1 = [1,2,3]

list_2 = list_1

print("原始列表")

print(list_1)

print(list_2)

list_1 = [4,5,6]

print("第一次变值")

print(list_1)

print(list_2) #list_2没有改变

##

# 列表,第二种变值

#

##

list_3 = [1,2,3]

list_4 = list_3

print("原始列表")

print(list_3)

print(list_4)

list_3.append(5)

print("第二次变值")

print(list_3)

print(list_4) #list_4发生改变

上面列表直接赋值中,list_1由[1,2,3]改为[4,5,6],相当于重新开辟了一个[4,5,6]对象的内存空间,并将list_1指向了该空间。该过程中,之前指定的list_2的指向没有发生改变,依旧指向[1,2,3],所以list_2没有发生变化;

list_3由[1,2,3]通过append(5)方法在尾部插入新值,[1,2,3]内存空间扩充,但list_3指向并没有发生变化,同时该过程中,list_4也依旧指向该空间,所以list_4一同发生变化。

# 元祖

tup_1 = (1,2,3,4,5)

tup_2 = tup_1

tup_1 = (6,7,8,9,10)

#tup_1 = tup_1+(6,7,8,9,10)

元祖确定后,重新赋值tup_1或者将两个元祖合并到tup_1,tup_2也不会发生变化。

# 字典

dict_1 = {"a":11,"b":22,"c":33,"d":44}

dict_2 = dict_1

dict_1.popitem()#dict_1 dict_2都发生变化

dict_1.popitem()是对原来的字典内存空间技能操作,dict_1、dict_2都指向该空间,所以都会发生变换。

# 集合

set_1 = {1,2,3,4,5}

set_2 = set_1

#set_2 = cp.copy(set_1)

set_1.add(6)

直接赋值,改变set_1后set_2也会发生改变,浅拷贝后不会改变。

浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象

深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象

import copy as cp

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

b = a #赋值。传对象的引用

c = a[:] #利用分片操作进行拷贝(浅拷贝)

d = cp.copy(a) #对象拷贝,浅拷贝

e = cp.deepcopy(a) #对象拷贝,深拷贝

a.append(5) #改动对象a

a[4].append('c') #改动对象a中的['a', 'b']列表子对象

print(a)#[1, 2, 3, 4, ['a', 'b', 'c'], 5]

print(b)#[1, 2, 3, 4, ['a', 'b', 'c'], 5]

print(c)#[1, 2, 3, 4, ['a', 'b', 'c']]

print(d)#[1, 2, 3, 4, ['a', 'b', 'c']]

print(e)#[1, 2, 3, 4, ['a', 'b']]

b是a的一个引用,两者指向的对象同样,打印结果必定同样。d是a的一个浅拷贝,对 a中的父对象(指向了第一层元素,1,2,3,4,[‘a’, ‘b’]内存空间),添加的第一层元素5后,不会发生变化。但其中对象的子对象发生更新(a[4]添加‘c’后),d也发生改变。c也是浅拷贝,同理。e是a的深拷贝,父对象子对象都会进行拷贝。

其实,浅拷贝,深拷贝底层还是变量对内存空间指向层级的不同。

直接复制(引用):数据都指向最顶层的内存空间

a = [1,2,3,4,[‘a’,‘b’]]

b = a

d4ec123ca2d6dcc11c1e7386b2e9f49e.png

浅拷贝:指向父对象内存空间

a = [1,2,3,4,[‘a’,‘b’]]

b = copy.copy(a)

f784209e19c7deb9ceb9bb79551b23ee.png

深拷贝:指向父对象及其所有子对象内存空间

a = [1,2,3,4,[‘a’,‘b’]]

b = copy.deepcopy(a)

93c2d4786cb0fdb20b0881f850b8a22a.png

原文链接:https://blog.csdn.net/weixin_41746317/article/details/106505390


版权声明:本文为weixin_28729843原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。