一、浅拷贝
Python中不但变量名无需事先声明,而且也无需类型声明。
在Python语言中,对象的类型和内存占用都是运行时确定的。
在赋值时解释器会根据语法和右侧的操作数来决定新对象的类型。
在对象创建后,一个该对象的引用会被赋值给左侧的变量。
copy模块用于对象的拷贝操作。
该模块只提供了两个主要的方法:
copy.copy与copy.deepcopy,
分别表示浅拷贝与深拷贝
# a = [11,12]
# b = a
# print(id(a)) #列表是可变类型 每次刷新系统都会随机非配内存空间
# print(id(b))
# copy.copy
# 浅拷贝 浅拷贝只会拷贝第一层
# 浅拷贝是对于一个对象的顶层拷贝
# 通俗的理解是:拷贝了引用,并没有拷贝内容
a = [11, 22]
b = [33, 44]
c = [a, b]
# print(id(a))
# print(id(b))
# # print(c)
# print(id(c))
#
import copy
d = copy.copy(c)
# print(id(d))
# print(d) #[[11, 22], [33, 44]]
# print(id(d[0]))
# print(id(d[-1]))
总结:
浅拷贝是对于一个对象的顶层拷贝,相当于只拷贝了最浅的一层或者第一层。
通俗的理解是:拷贝了引用,并没有拷贝内容
二、深拷贝
copy.deepcopy
深拷贝 深拷贝会完全复制原变量的所有数据(递归性质的拷贝),在内存中生成一套完全一样的内容
我们对这两个变量中的一个进行任意修改都不会影响另一个变量。
# a = [11,12]
# b = [22,23]
# c = [a,b]
# print(id(c))
#
# import copy
#
# d = copy.copy(c)
# print(id(d))
#
# c[0].append(55)
# print(c)
# print(b)
深拷贝总结:
深拷贝会完全复制原变量的所有数据(递归),
在内存中生成一套完全一样的内容,
我们对这两个变量中的一个进行任意修改都不会影响另一个变量。
深拷贝和浅拷贝之间的区别是什么?
对象的赋值就是简单的引用,a = [1,2,3], b=a, 在上述情况下,a和b是一样的,他们指向同一片内存,b不过是a的别名,是引用,我们可以使用b is a 去判断,返回True,表名他们地址相同内容也相同,也可以使用id()函数来查看.看两个列表地址是否相同.
深拷贝就是将一个对象拷贝到另一个对象中,这意味着如果你对一个对象的拷贝做出改变时,不会影响原对象。在Python中,我们使用函数deepcopy()执行深拷贝
import copy
b=copy.deepcopy(a)
而浅拷贝则是将一个对象的引用拷贝到另一个对象上,所以如果我们在拷贝中改动,会影响到原对象。我们使用函数function()执行浅拷贝
b=copy.copy(a)
切片操作是浅拷贝
工厂函数是浅拷贝:lst1 = list(lst)
copy函数:lst1 = copy.copy(lst)
注意一点,浅拷贝要分三种情况进行讨论
1.拷贝不可变对象:只是增加一个指向原对象的引用,改变会互相影响。
>>> a = (1, 2, [3, 4])
>>> b = copy.copy(a)
>>> b
... (1, 2, [3, 4])
# 改变一方,另一方也改变
>>> b[2].append(5)
>>> a
... (1, 2, [3, 4, 5])
2.拷贝可变对象(一层结构):产生新的对象,开辟新的内存空间,改变互不影响。
>>> import copy
>>> a = [1, 2, 3]
>>> b = copy.copy(a)
>>> b
... [1, 2, 3]
# 查看两者的内存地址,不同,开辟了新的内存空间
>>> id(b)
... 1833997595272
>>> id(a)
... 1833997595080
>>> a is b
... False
# 改变了一方,另一方关我卵事
a = [1, 2, 3] b = [1, 2, 3]
>>> b.append(4)
>>> a
... [1, 2, 3]
>>> a.append(5)
>>> b
... [1, 2, 3, 4]
3.拷贝可变对象(多层结构):产生新的对象,开辟新的内存空间,不改变包含的子对象则互不影响、改变包含的子对象则互相影响。
>>> import copy
>>> a = [1, 2, [3, 4]]
>>> b = copy.copy(a)
>>> b
... [1, 2, [3, 4]]
# 查看两者的内存地址,不同,开辟了新的内存空间
>>> id(b)
1833997596488
>>> id(a)
1833997596424
>>> a is b
... False
# 1.没有对包含的子对象进行修改,另一方关我卵事
a = [1, 2, [3, 4]] b = [1, 2, [3, 4]]
>>> b.append(5)
>>> a
... [1, 2, [3, 4]]
>>> a.append(6)
>>> b
... [1, 2, [3, 4], 5]
# 2.对包含的子对象进行修改,另一方也随之改变
a = [1, 2, [3, 4]] b = [1, 2, [3, 4]]
>>> b[2].append(5)
>>> a
... [1, 2, [3, 4, 5]]
>>> a[2].append(6)
>>> b
... [1, 2, [3, 4, 5, 6]]
注意点:
浅拷贝对不可变类型和可变类型的copy不同
copy.copy对于可变类型,会进行浅拷贝
copy.copy对于不可变类型,不会拷贝,仅仅是内存意义上的指向
is ==
== 比较的是两个对象的内容是否相等,即内存地址可以不一样,内容一样就可以了。
is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同。
# a = [11,22]
# b = [11,22]
# # print(id(a))
# # print(id(b))
#
# if a == b:
# print('意思相等,地址不一')
#
#
# if a is b:
# print('a 是 b,地址相等')
- Post link: https://yanxiang.wang/python%E6%B7%B1%E6%B5%85%E6%8B%B7%E8%B4%9D%E7%9A%84%E5%8C%BA%E5%88%AB/
- Copyright Notice: All articles in this blog are licensed under unless otherwise stated.