Python
中,对象的赋值,拷贝(深/浅拷贝)之间是有差异的 。本文中重点讲解下Python
中的深浅拷贝知识点
- 内存相关
- 浅拷贝
- 深拷贝
内存相关
赋值和修改内存地址中的数据
查看内存地址id()
函数
-
实例一
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
a1 = [1,2,3]
a2 = [1,2,3]
v1 = 666
v2 = 666
v1 = "abcd"
v2 = "abcd"
print(id(a1), id(a2))
print(id(v1), id(v2))
print(id(v3), id(v4))
# 内存地址:结果本应该是不同的,由于Python中小数据池的缓存机制,使得某些情况下内存地址相同
2072273207688 2072273971080
2072273946608 2072273945584
2072274079000 2072274079000 -
实例二
1
2
3
4
5
6
7
8
9# 实例2
v5 = [1,3,4,5]
print(id(v5))
v5 = [1,3,4]
print(id(v5))
# 开辟新的内存,存放不同的数据
2072291579016
2072291262600 -
实例三
1
2
3
4
5
6
7
8
9v6 = [1,3,4,8]
v7 = v6
v6.append(888)
print(v7) # [1, 3, 4, 8, 888]
v6 = [1,3,4,8]
v7 = v6 # v7和v6指向同一个内存地址
v6 = [1,3,888] # 开辟了新的内存地址,存放数据;v7是不会变的
print(v7) # [1,3,4,8] -
实例四
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18v1 = [1,2]
v2 = [3,4,v]
# 练习题1
v1.append(99)
print(v2) # [3,4,[1,2]]
# 练习题2
v2[2].append(999)
print(v1) # [1,2,999]
# 练习题3
v1 = 888
print(v2) # [3,4,[1,2]]
# 练习题4
v2[2] = 666
print(v1) # [1,2]结论
-
赋值:凡是赋值都不影响
-
修改内存地址:只有修改内存中数据才会影响
小数据池机制
整数在程序中的使用非常广泛,Python为了优化速度,使用了小整数对象池, 避免为整数频繁申请和销毁内存空间。 Python认为其内存是不变的,做了缓存。列表、元组、集合、字典等不会做缓存
数字:-5~256
字符串:“abcd”,出现特殊字符则内存地址不同
v1和v2的内存地址理应不同,但是由于小数据池机制,变得相同;a1和a2同理。
v3和v4:在系统中重新开辟了内存
== 和is区别
== :比较值是否相等
is
:判断内存地址是否相同
浅拷贝copy
不管是浅拷贝还是深拷贝,都会开辟新的内存
浅拷贝只拷贝第一层
1 |
# 浅拷贝 |
深拷贝deepcopy
拷贝所有的可变类型数据
1 |
# 深拷贝 |
- 浅拷贝:copy(),拷贝第一层
- 深拷贝:deepcopy(),拷贝所有可变类型的数据;存在嵌套时,深浅拷贝才有区别
对于字符串
str
、整数型int
、布尔值bool
三种不可变的对象类型,深浅拷贝是一样的,直接在内存中直接开辟空间进行存储。
特殊情况
元组是不可变类型,当里面的元素全部是不可变类型时,深浅拷贝没有区别;只有当里面的元素由可变类型(比如列表时),才会有区别。
1 |
import copy |
近期评论