一、先来两段代码!
a = 100def beyond(num):num+=numprint(num)beyond(a)#结果为:200
print(a)#结果为:100
a = 100def beyond(num):num=num+numprint(num)beyond(a)#结果为:200
print(a)#结果为:100
通过这两段代码的结果可以看出,最终的结果和大家想的完全一样。
但事实这两段代码是完全等价的嘛?答案是否定的,要是是完全一样我写这篇博客闲着没事干哈。
废话不多说,下面进入正题。
在Python中列表
、字典
是可变数据类型;可变数据类型在定义字典的时候是不可以当key的,可以当value,因为key有个hash过程。
如果一个变量指向一个全局变量,那么想要修改这个全局变量,就得看下这个全局变量是不是可变数据类型。以这两段代码为例,a=100,这里变量a指向全局变量100,需要修改100,得看下100这个整型数是不是可变数据类型。很显然,不是!
分析一下程序执行过程:
①a = 100 #先定义一个内存空间1存储100,变量a指向这个列表1
②def beyond(num): #程序运行到这里时,系统已明确这个函数需要有一个参数,由于Python是动态语言(第四部分中有解释),故此时尚未清楚这个函数具体实现的功能是什么。
③beyond(a) #这里变量a指向谁,也会将函数中形参num也指向谁,这里均指向内存空间1
④当程序运行到函数beyond(num)时,:
- 若num+=num #其实遇到
+=
是有两个过程要完成
1,首先判断能否对这个num值进行修改,即判断num是否是可变数据类型;若能修改直接在num上修改
2,若不能修改则需要重新定义一个变量,让这个变量再重新指向这个值;即系统会重新定义内存空间2,用来存放num+num的值。即此时的num指向内存空间2,内存空间2存放num+num的值。 - 若num=num+num #遇到
=
直接重新定义一个变量,让这个变量再重新指向这个值;即系统会重新定义内存空间2,用来存放num+num的值。即此时的num指向内存空间2,内存空间2存放num+num的值。
⑤print(num)
⑥print(a)
若为num = num + num 即先算等号右边,会的到一个临时的答案,得到这个临时的答案相当于在内存中额外开辟了一块内存;等号左边则会指向这个额外开辟内存而已,所以a所指向的那块地方没有任何的变化,只不过在函数里面发生了变化,而在函数外面a的值并未发生任何变化。
到这里是不是有那么一点略懂了?哈哈哈,来继续深入一点!
二、再来两段代码!
a = [100]def beyond(num):num+=numprint(num)beyond(a)#结果为:[100, 100]
print(a)#结果为:[100, 100]
上述代码,很明显,遇到num+=num,其实说白了直接看+=
就行,遇到+=
先判断num是否可以修改,很显然,a指向列表1,存放[100],列表是可变数据类型,直接再列表1中进行了修改,a指向列表1,num指向列表1,而指向+=
操作的时候是直接针对的列表1操作的,故a和num的最终值都是已经改变之后的值,即[100,100]。
a = [100]def beyond(num):num=num+numprint(num)beyond(a)#结果为:[100, 100]
print(a)#结果为:[100]
而这段代码,a = [100],系统会为列表100分配内存空间,变量a会指向这个内存空间;接着是是num=num+num,系统会重新分配一个新的内存空间,存放num+num运算结果,num最终指向这个新的内存空间。a所指向的内存空间存放列表[100],而num指向的新的内存空间存放的是num+num的结果即[100,100]。这些输出结果就可想而知了吧~
总结:num+=num并不等价于num=num+num,若是数字,答案是一样的,但是真正的原理并不相同。因为Python语言当中,并不是值赋值,而是引用。所有的只要牵涉到等号,统统都是引用,
好了,到此结束,是不是有那么一丢丢感觉了?