变量:是一个系统表的元素,拥有指向对象的连接空间
对象:被分配的一块内存,存储其所代表的值
引用:是自动形成的从变量到对象的指针
注意:类型(int类型)属于对象,不是变量
不可变对象:一旦创建就不可修改的对象,包括字符串、元组、数字
可变对象:可以修改的对象,包括列表、字典。
在Python中对象的赋值其实就是对象的引用。当创建一个对象,把它赋值给另一个变量的时候,python并没有拷贝这个对象,只是拷贝了这个对象的引用而已。
浅拷贝:拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已。也就是,把对象复制一遍,但是该对象中引用的其他对象我不复制。
深拷贝:外围和内部元素都进行了拷贝对象本身,而不是引用。也就是,把对象复制一遍,并且该对象中引用的其他对象我也复制。
应用的范围:
深浅拷贝的作用:
>>> a="1234567"
>>> b=a
>>> id(a)
4367619440
>>> id(b)
4367619440
>>> c=copy.copy(a)
>>> id(c)
4367619440
>>> d=copy.deepcopy(a)
>>> id(d)
4367619440
Python 存储变量的方法跟其他 OOP 语言不同。它与其说是把值赋给变量,不如说是给变量建立了一个到具体值的 reference。
当在 Python 中 a = something 应该理解为给 something 贴上了一个标签 a。当再赋值给 a 的时候,就好象把 a 这个标签从原来的 something 上拿下来,贴到其他对象上,建立新的 reference。 这就解释了一些 Python 中可能遇到的诡异情况:
>>> a = [1, 2, 3]
>>> b = a
>>> a = [4, 5, 6] //赋新的值给 a
>>> a
[4, 5, 6]
>>> b
[1, 2, 3]
# a 的值改变后,b 并没有随着 a 变
>>> a = [1, 2, 3]
>>> b = a
>>> a[0], a[1], a[2] = 4, 5, 6 //改变原来 list 中的元素
>>> a
[4, 5, 6]
>>> b
[4, 5, 6]
# a 的值改变后,b 随着 a 变了
=
(赋值) 浅拷贝:值相等,地址相等copy
浅拷贝:值相等,地址不相等deepcopy
深拷贝:值相等,地址不相等当浅复制的值是可变对象(列表和元组)时会产生一个“不是那么独立的对象”存在。有两种情况:
>>> l1=[1,2,3]
>>> l2=l1
>>> l3=copy.copy(l1)
>>> id(l1)
4367654664
>>> id(l2)
4367654664
>>> id(l3)
4367628616
>>> l1.append(55)
>>> print(l1)
[1, 2, 3, 55]
>>> print(l3)
[1, 2, 3]
>>> import copy
>>> list1=[1,2,['a','b']]
>>> list2=list1
>>> list3=copy.copy(list2)
>>> list4=copy.deepcopy(list3)
>>> id(list1)
4338414656
>>> id(list2)
4338414656
>>> id(list3)
4338415016
>>> id(list4)
4338414368
>>> list1[2].append('a')
>>> id(list1)
4338414656
>>> print list1
[1, 2, ['a', 'b', 'a']]
>>> print list3
[1, 2, ['a', 'b', 'a']]
>>> print list4
[1, 2, ['a', 'b']]
探讨:对于一个复杂对象的浅copy,在copy的时候到底发生了什么?
>>> import copy
>>> origin = [1, 2, [3, 4]]
#origin 里边有三个元素:1, 2,[3, 4]
>>> cop1 = copy.copy(origin)
>>> cop2 = copy.deepcopy(origin)
>>> cop1 == cop2
True
>>> cop1 is cop2
False
#cop1 和 cop2 看上去相同,但已不再是同一个object
>>> origin[2][0] = "hey!"
>>> origin
[1, 2, ['hey!', 4]]
>>> cop1
[1, 2, ['hey!', 4]]
>>> cop2
[1, 2, [3, 4]]
#把origin内的子list [3, 4] 改掉了一个元素,观察 cop1 和 cop2
shallow copy
概念图如下:shallow copy(浅复制)对于一个复杂对象的子对象并不会完全复制,什么是复杂对象的子对象呢?就比如序列里的嵌套序列,字典里的嵌套序列等都是复杂对象的子对象。对于子对象,python会把它当作一个公共镜像存储起来,所有对他的复制都被当成一个引用,所以说当其中一个引用将镜像改变了之后另一个引用使用镜像的时候镜像已经被改变了。
deepcopy
概念图如下:deepcopy的时候会将复杂对象的每一层复制一个单独的个体出来。
这时候的 origin[2] 和 cop2[2] 虽然值都等于 [3, 4],但已经不是同一个 list了。即我们寻常意义上的复制。
参考文章: https://blog.csdn.net/u011630575/article/details/78604226#commentBox
https://blog.csdn.net/u014745194/article/details/70271868