文章目录
引用
1、引用即程序中的数据在内存中的地址。比如a=‘abc’,变量a存储的是字符串’abc’在内存中的地址
2、可以用 id(变量名) 查看变量的内存地址
a = 'abc'
print(id(a))
3、若将变量a赋值与变量b,那么变量b的内存地址与变量a是一样的
a = 'abc'
b = a
print(id(a))
print(id(b))
4、若给变量a重新赋值,则a的内存地址改变,b的内存地址不变。所以这种情况下,打印两个变量得到的结果是不同的
a = 'abc'
b = a
a = 123
print(id(a))
print(id(b))
可变类型和不可变类型
1、可变类型:可以在原数据的基础上进行修改,修改后内存地址不变
2、不可变类型:不能在原数据基础上进行修改,重新赋值后内存地址改变
3、常见的可变类似:列表、字典、集合
常见的不可变类型:字符串、数字、元组
深拷贝和浅拷贝
1、浅拷贝中,变量都指向同一个内存地址;深拷贝中,变量都有自己独立的内存地址,不受其他变量改变的影响
2、给变量赋值变量就是典型的浅拷贝。赋值默认传递数据的引用,当其中一个变量改变数据时,另一个变量也同时发生改变
3、copy的使用:copy在不同的条件下,既能做到深拷贝,也能做到浅拷贝
copy作为深拷贝的例子:
下方变量a与变量b的内存地址是不一致的,且对a进行修改后,b的值不变。在这种情况下,copy能够作为深拷贝使用
import copy
a = [1,2,3]
b = copy.copy(a)
a.append(4)
print(a) -> 输出[1, 2, 3, 4]
print(b) -> 输出[1, 2, 3]
copy作为浅拷贝的例子:
可以看到在下方例子中,当变量a列表中作为元素的列表变化后,变量b也同时发生了改变
import copy
a = [1,2,3,['a','b']]
b = copy.copy(a)
a[3].append('c')
print(a) -> 输出[1, 2, 3, ['a', 'b', 'c']]
print(b) -> 输出[1, 2, 3, ['a', 'b', 'c']]
可以理解为,变量a本身指向了其赋值数据的内存地址,但是变量a内其实还有一个列表,这个作为元素的列表本身是另外有指向的内存地址的。当用copy进行拷贝时,变量b中作为元素的列表,其指向其实和变量a中元素列表是一样的(a与b共享子对象)
4、对copy的使用做一个总结:如果变量只有一层,那么copy就能做到深拷贝;如果变量有多层,那么copy只能拷贝第一层,是浅拷贝
5、如果想用copy来做到对多层变量的深拷贝,可以用.deepcopy()
import copy
a = [1,2,3,['a','b']]
b = copy.deepcopy(a)
a[3].append('c')
print(a) -> 输出[1, 2, 3, ['a', 'b', 'c']]
print(b) -> 输出[1, 2, 3, ['a', 'b']]