Python中临时变量为何改变传共享变量的行为?
问题解答
这个问题的核心是Python表达式的求值顺序,和递归、传共享机制无关,本质是复合表达式中各部分的计算时机不同。
先明确Python的求值规则
Python对表达式的计算遵循从左到右的顺序:
- 对于
x += y这类复合赋值,会先计算x的当前值,再计算y,最后将x + y的结果赋值给x。 - 对于拆分的两步写法(先算
y,再算x += y),则会先完成y的计算,再取x的当前值进行运算。
逐流程分析两种写法的差异
写法1:holder.val += self.diveDeeper(holder, n-1)
以n=5为例,执行流程如下:
- 进入
diveDeeper(holder,5),先计算holder.val的当前值(初始为0),然后调用递归diveDeeper(holder,4)。 - 进入
diveDeeper(holder,4),同样先取holder.val(还是0),再调用diveDeeper(holder,3)。 - 以此类推,直到
n=0,直接返回1。 - 回到
n=1的调用:此时之前已经取到的holder.val是0,加上递归返回的1,赋值给holder.val(变为1),打印1后返回1。 - 回到
n=2的调用:之前取的holder.val是0(还没被n=1的调用修改),加上返回的1,赋值为1,打印1后返回1。 - 后续n=3、4、5的调用逻辑完全一致,最终所有打印结果都是1。
写法3:拆分两步执行
returnVal = self.diveDeeper(holder, n-1) holder.val += returnVal
同样以n=5为例:
- 进入
diveDeeper(holder,5),先调用diveDeeper(holder,4),这个递归会完整执行完所有内层逻辑。 - 内层
n=4的调用会先执行diveDeeper(holder,3),直到n=0返回1。 - 回到
n=1:先拿到递归返回的1,此时holder.val还是0,执行holder.val +=1后变为1,打印1并返回1。 - 回到
n=2:先拿到n=1返回的1,此时holder.val已经被n=1修改为1,执行holder.val +=1后变为2,打印2并返回1。 - 回到
n=3:此时holder.val是2,加1后变为3,打印3并返回1。 - 回到
n=4:holder.val是3,加1后变为4,打印4并返回1。 - 回到
n=5:holder.val是4,加1后变为5,打印5并返回1。
最终输出就是1、2、3、4、5。
补充说明写法2的结果
写法2holder.val = holder.val + self.diveDeeper(holder, n-1)和写法1本质完全一致:等号右边会先计算holder.val的当前值,再计算递归调用,所以结果和写法1相同,这也说明问题和+=运算符无关,纯粹是求值顺序导致的。
内容的提问来源于stack exchange,提问作者Ahmad Mudaafi'
相关产品推荐
相关产品推荐

