直到面试被问到什么是「共享引用」,我才发现对于它的一无所知...

来自:Python空间(微信号:Devtogether),作者:Rocky0429



00.写在之前


不知道你有没有过这种囧境,有时候突然被问到一个问题,你嘴角轻扬,潜意识里觉得这个简单问题必是随口就来,正待挥斥方裘激扬文字,嘴巴一张,嘤嘤嘤???


直到自己开始真正的去写技术文章,才真正发现看过和能用自己的语言清楚的描述是两种情况,所以还请大家对文字怀有一点敬畏之心,在嗤之以鼻之前请先好好想一下自己是不是也能写的别人能看懂。


01.共享引用


相信很多人的 Python 生涯都写过下面这样的代码:


>>> a = 'Rocky'
>>> b = a


上面对 a 进行了赋值,然后又创建了对象 b,最终形成了如下图所示的结果:



由上图我们可以很清楚看出,b = a 中的 a 被替换成了其引用的对象 'Rocky',从而 b 也成了这个对象的一个引用。实际形成的效果就是变量 a 和 b 都引用了相同的对象(即指向了相同的内存空间)。


这种多个变量名引用了同一个对象,在 Python 中就叫做「共享引用」。


为了更好的理解,我们再看下面这种情况:


>>> a = 'Rocky'
>>> b = a
>>> a = 233


对于 Python 的赋值语句来说,a = 233 简单的创建了一个新的对象(代表整数值 233),并设置 a 对这个新的对象进行引用。尽管如此,这个并不会改变 b 的值,因为这个赋值元算改变的不是对象 'Rocky',仅仅改变了变量 a,所以 b 并没有发生改变,仍然引用的是刚开始的对象 'Rocky',具体情形如下所示:



同理,如果把 b 改成 233 的话,也会发生同样的事:赋值只会改变 b,不会对 a有影响。发生这种现象,跟没有类型差异是一样的。


接下来,我们再来看下面的这个例子:


>>> a = 233
>>> b = a
>>> a = a + 1


在这里,a 和 b 各自的结果是什么呢?我们先来揭晓一下结果:


>>> a
234
>>> b
233


同样的结果,a 变了,b 不变。


Python 先让变量 a 引用了对象 3,让 b 引用了与 a 同样的对象,在之前的例子中是让 a 设置为一个完全不同的对象,在这里的 244 是表达式 “+“ 的计算结果,其实一个道理,并不会对 b 产生什么作用。事实上,是没有办法改变对象 233 的值的,就像我在之前写整数的时候说过的「整数是不可变的」,所以不可能在原处修改它。


02.写在之后


其实还是之前老生常谈过的问题,认识这样现象的一种方法就是时时刻刻记住,在 Python 中,变量就是指向对象的指针,而不是可以改变的内存区域的标签。给一个变量赋一个新值,并不是替换了原先的旧的对象,实际上是让这个变量去引用完全不同的一个新对象,实际效果就是仅仅影响的是那个被赋值的变量。


但这个也不是绝对的,当某些可变的对象以及原处的改变被带进来的时候,这个情形会发生某种改变,想知道这是一种怎样的变化的话,敬请期待之后的文章。


那我们下次见喽。

推荐↓↓↓
Python编程
上一篇:曾经,我被Python这些陷阱坑的找不着北... 下一篇:聊一聊 Python 对象的「垃圾收集」那些事儿。