当我们执行递归函数时,会发现递归函数中调用递归之前的语句和递归之后的语句执行顺序是相反的。我们通过一个例子来看:
def up_and_down(n):print("Level " + str(n) + ":location " + str(id(n))) #1if n<4:up_and_down(n+1)print("Level " + str(n) + ":location " + str(id(n))) #2
def main():up_and_down(1)if __name__ == "__main__":main()
Level 1:location 94865315079104
Level 2:location 94865315079136
Level 3:location 94865315079168
Level 4:location 94865315079200
Level 4:location 94865315079200
Level 3:location 94865315079168
Level 2:location 94865315079136
Level 1:location 94865315079104
可以看到,main函数首先使用参数1调用了递归函数【up_and_down】,此时执行print语句输出【Level 1:location 94865315079104】。
接下来,由于n=1<4成立,使用参数2调用递归函数【up_and_down】,此时执行print语句输出【Level 2:location 94865315079136】。
再接下来,由于n=2<4成立,使用参数3调用递归函数【up_and_down】,此时执行print语句输出【Level 3:location 94865315079168】。
再接下来,由于n=3<4成立,使用参数4调用递归函数【up_and_down】,此时执行print语句输出【Level 4:location 94865315079200】。
再接下来,由于n=4<4不成立,不再调用递归函数【up_and_down】。此时调用递归函数后的print语句输出【Level 4:location 94865315079200】。这一层的调用结束。把控制权给到这个函数的调用函数,即上一层递归函数。这一层递归函数在【调用下一层递归函数】前的语句已经执行,所以继续执行后面的print语句输出【Level 3:location 94865315079168】。
同理,再执行上一层的递归函数后的print语句输出【Level 2:location 94865315079136】。
再执行上一层的递归函数后的print语句输出【Level 1:location 94865315079104】。
此时,整个调用函数执行结束。
从上面的输出结果中,我们可以看到,每一层的递归都使用自己的私有的变量,通过查看变量的地址能证明这一点。
递归的基本原理:
1、每一次递归函数调用都会有一次返回。当程序流执行到某一级递归的结尾处时,会转移到前一级递归继续执行;
2、递归函数中,位于递归调用前的语句和各级被调用函数具有相同的执行顺序。如print语句【#1】位于递归调用语句前,它按照递归调用的顺序执行了4次;
3、每一级的函数调用都有自己的私有变量;
4、递归函数中,位于递归函数调用语句后的语句的执行顺序和各个被调用函数的顺序相反;
5、虽然每一级递归都有自己的变量,函数的代码并不会得到复制;
6、递归函数中必须包含可以终止递归调用的语句。
参考
递归函数执行顺序_递归函数的执行顺序_文峰哥的博客-CSDN博客