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)