视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
理解Python赋值与拷贝
2020-11-27 14:12:51 责编:小采
文档
 本文实例讲述了理解Python赋值与拷贝。分享给大家供大家参考,具体如下:

变量与赋值

在 Python 中,一切皆为对象,对象通过「变量名」引用,「变量名」更确切的叫法是「名字」,好比我们每个人都有自己的名字一样,咱们通过名字来代指某个人,代码里面通过名字来指代某个对象。

变量赋值就是给对象绑定一个名字,赋值并不会拷贝对象。好比我们出生的时候父母就要给我们取一个名字一样,给人取个绰号并不来多出一个人来,只是多一个名字罢了。

两个对象做比较有两种方式,分别是:is 与 == , is 比较的是两个对象是否相同,通过对象的ID值可识别是否为相同对象,== 比较的是两个对象的值是否相等

>>> x1 = [1,2]
>>> x2 = [1,2]
>>> x1 is x2
False

>>> id(x1)
4338854088
>>> id(x2)
43304392

>>> x1 == x2
True

x1 和 x2 的值虽然相同,但在内存中是两个的不同的对象,占据不同的内存空间,就好比两个长得一样的苹果摆在桌子上,实则为两个不同的物体。

>>> x3 = x2
>>> x3 is x2
True
>>> id(x3)
43304392

前面说了,赋值是给对象绑定名字,这里我们只不过是给 x2 对应的那个对象绑定了一个新的名字叫 x3,这就好比桌上放了一个苹果,开始给它贴了一个 x2 的标签,后来又给它添了一个 x3 的标签,本质上还是同一个苹果,所以,x2 和 x3 所指的其实是同一个对象。

通过x2 修改对象时,x3 也会跟着变化,因为本质上它们是同一个对象,这就好比张三和小张是同一个人时,给张三添衣服其实就是给小张添衣服。

>>> x2.append(3)
>>> x2
[1, 2, 3]
>>> x3
[1, 2, 3]

但是,当我给 x2 重新赋值时,相当于 x2 不再引用之前的对象,而引用新对象, x3 依然引用之前的对象。好比桌上一大苹果开始贴了 x2 和 x3 两个标签,给 x2 重新赋值就相当于把 x2 标签贴到另外一个苹果,但是 x3 还是贴在老苹果身上。

>>> x2 = [3, 4]
>>> x3
[1, 2, 3]

对象拷贝

在业务中有时我们需要复制一个对象,但是又不想对原对象产生副作用,肯定不能通过赋值给一个新变量来解决(因为赋值不是拷贝对象),所以 Python 专门提供了一种拷贝机制,基于原对象快速创建出一个含有相同值的对象。该功能由 copy 模块提供。

拷贝又分为浅拷贝和深拷贝。

>>> s = [1,2,3]
>>> sc = copy.copy(s) # 浅拷贝
>>> sc
[1, 2, 3]
>>> sdc = copy.deepcopy(s) # 深拷贝
>>> sdc
[1, 2, 3]

拷贝出来的对象只是值相同,实为不同的对象

>>> s == sc == sdc 
True
>>> s is sc
False
>>> s is sdc
False

那么浅拷贝(shallow copy)与深拷贝(deep copy)有什么区别呢?

对于不可变对象,比如整数、字符串、元组、还有由这些不可变对象组成的集合对象,浅拷贝和深拷贝没有区别,都是拷贝一个新对象

两者的区别在于拷贝组合对象,比如列表中还有列表,字典中还有字典或者列表的情况时,浅拷贝只拷贝了外面的壳子,里面的元素并没有拷贝,而深拷贝则是把壳子和里面的元素都拷贝了一份新的。

来看一个例子:

>>> x = [2, 3]
>>> y = [7, 11]
>>> z = [x, y]

>>> a = copy.copy(z) # 浅拷贝
>>> a[0] is z[0]
True

拷贝出来的对象 a 中的元素引用的是 x 和 y,当你修改 x 的值,a 也会跟着变。

>>> b = copy.deepcopy(z) # 深拷贝
>>> b[0] is z[0]
False

对于深拷贝,里面的元素也重新拷贝了一份,拷贝了一份与x和y等值的两个元素,修改 x 和 y 的值,不会对 b 产生影响

对列表的切片拷贝 z[:] 或者是调用对象的copy方法 list.copy() 都属于浅拷贝。对于自定义对象,我们还可以自己实现 __copy__方法和 __deepcopy__方法

相关阅读:

Django入门实践指南-第1部分
厉害了,10行代码实现抽奖助手自动参与抽奖
看了很多代码,却依然无从下手?

下载本文
显示全文
专题