父对象、子对象以及直接赋值、浅拷贝(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
在这里插入图片描述

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

a = [1,2,3,4,[‘a’,‘b’]]
b = copy.copy(a)
在这里插入图片描述

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

a = [1,2,3,4,[‘a’,‘b’]]
b = copy.deepcopy(a)
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值