拷贝
赋值
-
可变数据类型: 当该数据类型的对应变量的值发生了改变,那么它对应的内存地址不发生改变。
-
所以两个变量还是指向同一内存空间修改前者,后者也会变,反之亦然。
li1 = [1, 2] li2 = li1 print(id(li1), id(li2)) # 地址相同 3063790813256 3063790813256 # 修改li2,li1也会变 li2.append(3) print(li1) # [1, 2, 3] print(li2) # [1, 2, 3] print(id(li1), id(li2)) # 1491225460808 1491225460808 # 反之,修改li1 li2也会发生改变,因为他们的所指向的内存地址一致
-
不可变数据类型: 当该数据类型的对应变量的值发生了改变,那么它对应的内存地址也会发生改变。
b1 = 3 b2 = b1 print(b1, b2) # 3 3 b2 = 5 print(b1, b2) # 3 3 print(id(b1), id(b2)) # 140714965433472 140714965433536
拷贝
拷贝: 不管怎么拷贝,都是复制原数据产生一个新的数据并且将新数据的地址返回。
浅拷贝
copy 模块的 copy 方法,拷贝父对象,不会拷贝父对象的内部的子对象数据,而是拷贝的子对象引用(地址值)。
from copy import copy, deepcopy
# 拷贝父对象,不会拷贝对象的内部的子对象。
li1 = [1, 2, [2, 3]]
li2 = copy(li1)
print(li1)
print(li2)
"""
[1, 2, [2, 3]]
[1, 2, [2, 3]]
"""
print('修改列表中不可变类型元素')
li1[1] = 22
print(li1)
print(li2)
"""
修改列表中不可变类型元素,列表1改变,列表2没改变
[1, 22, [2, 3]]
[1, 2, [2, 3]]
"""
print('修改列表中的列表后')
li2[2][1] = 3
print(li1)
print(li2)
"""
修改列表中的列表后,列表1、2中的列表元素都发生了改变
[1, 22, [2, 4]]
[1, 2, [2, 4]]
"""
深拷贝
copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象的里面的数据或者属性。
from copy import copy, deepcopy
# 拷贝父对象,不会拷贝对象的内部的子对象。
li1 = [1, 2, [2, 3]]
li2 = deepcopy(li1)
print(li1)
print(li2)
"""
[1, 2, [2, 3]]
[1, 2, [2, 3]]
"""
print('修改列表中不可变类型元素')
li1[1] = 22
print(li1)
print(li2)
"""
修改列表中不可变类型元素,列表1改变,列表2没改变
[1, 22, [2, 3]]
[1, 2, [2, 3]]
"""
print('修改列表中的列表后')
li2[2][1] = 4
print(li1)
print(li2)
"""
修改列表中的列表后,列表2的列表元素发生了改变,列表1的列表元素没有发生了改变
[1, 22, [2, 3]]
[1, 2, [2, 4]]
"""
简述内存管理
- 内存管理: python内存管理是自动化(指的是对堆上的内存进行管理)
- 内存的开辟:
- 需要保存数据的时候系统就会自动在堆上开辟内存空间保存数据
- 注意:如果需要被保存的数据是数字或者字符串,系统会先检查专门保存数字字符串的的缓存区中是否已经存在这个数据,如果存在直接返回之前的数据的地址,不存在才会开辟新的内存去保存。(短小数字和字符串)
- 内存的释放(垃圾回收):
- Python中的每一个数据都有一个属性用来保存这个数据的引用个数(引用计数),当引用计数的值为0,那么这个数据就会自动销毁
- 简单来说,数据没有了引用就会销毁。