1.普通赋值拷贝
在python中,普通赋值拷贝:b=a
并不是重新开辟出一个空间保存a的信息,而是类似C语言中的指针,b是指向a指向的地址。
举一个栗子:有一个人叫小明,大家给他取了一个绰号叫狗剩,“狗剩”和“小明”都是指这个人,“狗剩”指的并不是另一个人。
a=[1,2]
b=a
print(id(a),id(b))
'''
输出结果:
3103405504576 3103405504576
'''
2.浅拷贝
(1)浅拷贝可变类型-copy.copy函数
浅拷贝:b=copy.copy(a)
当a是可变类型(比如列表、字典),这时b是直接开辟出一个新的空间去保存。但是对于a深层的数据,b仍是只保存其地址。即只对可变类型的第一层对象进行拷贝,对拷贝的对象开辟新的内存空间进行存储,不会拷贝对象内部的子对象。
举个栗子:小明在本子上写了语文书在书架上的位置,我看到后也抄写在我的本子上了。这时这两个数据并不在同一个本子上,我是拿着(开辟)另一个本子(空间)去拷贝。
但是需要注意的是:虽然这段指向语文书位置的文字不在一个本子上,但是都是指向的书架上的那本语文书,并不是指向另一本语文书。
import copy
a=[1,2]
b=[3,4]
c=[a,b]
d=copy.copy(c)
print(id(c),id(d))
print(id(c[1]),id(d[1]))
'''
输出结果:
2111496320192 2111496322432
2809475170880 2809475170880
'''
(2)浅拷贝不可变类型
浅拷贝不可变类型(比如元组),则并不会开辟一个新的空间去拷贝,而是和普通赋值拷贝一样,只是指向其内存地址
举个栗子:
如(1)中的栗子,因为人是独一无二不可能被复制的(不可变类型),想要对其通过起绰号而复制一个人这种情况是不可能的
import copy
a=(1,2)
b=copy.copy(a)
print(id(a),id(b))
'''
输出结果:
2262507779648 2262507779648
'''
3.深拷贝-copy.deepcopy函数
(1)深拷贝可变类型
深拷贝b=copy.deepcopy(a)
不仅对于该对象开辟新空间拷贝,对于其子对象同样如此
举个栗子:
明天上课要拿语文书,小明在本子上写了“语文书”,我看到后也抄写“语文书”在我的本子上帮助提醒自己明天别忘带。此时不仅“语文书”这三个字不在同一个本上,并且指的“语文书”也不是同一本语文书。
(2)深拷贝不可变类型-子对象有可变类型
若深拷贝不可变类型的子对象有可变类型,则会开辟新空间拷贝。
举个栗子:
小兰暗恋小明,看到小明有一本语文书,她也想要一本小明的语文书,为了满足小兰的愿望,小明又买了一本语文书然后送给小兰了。此时虽然小明是不可被拷贝的,但是小明的语文书可以被拷贝。
import copy
a=[1,2]
b=[3,4]
c=(a,b)
d=copy.deepcopy(c)
print(id(c),id(d))
'''
输出结果:
1954111551872 1954111551168
'''
(3)深拷贝不可变类型-子对象没有可变类型
深拷贝不可变类型的子对象没有可变类型,则并不会开辟新空间去拷贝。
举个栗子:
小兰也想要一个和小明亲生妈妈一样的亲生妈妈,小明是不可被复制的,小明亲生妈妈也是不可被复制的。
import copy
a=(1,2)
b=(3,4)
c=(a,b)
d=copy.deepcopy(c)
print(id(c),id(d))
'''
输出结果:
1954111717568 1954111717568
'''