python3 中双递归函数的调用过程详解与print()函数在程序调试过程中的作用

所有函数都可以被其他函数调用,当然也可以被自己调用,这种调用方式叫做递归。递归是简化代码的一种有效手段,也是体现代码美感的重要方式。

一般的书籍或教程讲到递归的时候都会以阶乘距离,这种案例只涉及到调用自己一次,所以较为简单,也比较容易理解。但是在实际使用中,我们会遇到在一个函数里,存在两个调用自身的函数,这个分析起来就比较困难,我们必须要理解“栈”的概念,才能顺利理解调用过程。

下面利用tutle绘图库来介绍双递归函数(即在一个函数里存在两个调用本函数的函数)的执行过程,同时介绍print()函数在此类函数调试中的积极作用。

题目:
理解如下代码的运行机理:
这里写图片描述
图中标注1为第一个调用自身的函数,标注2为第二个调用自身的函数。代码中加入了很多print()语句,用来根据输出判断程序的执行过程。这段代码的执行结果为:
这里写图片描述
这里写图片描述

主函数中调用语句为:

draw(bob,100,2)

从控制台输出结果我们可以看到,程序首先以 n=2 进入,再进入调用自身的函数1,再重新进入本函数,控制台输出“1 beginning”,当再次从语句1进入本函数时,出发 if 语句条件,直接跳到语句1后面开始继续执行。 (注意,此时并不会跳出整个函数结束)此时 n=1 ,所以进入语句2执行后立刻return到后面语句,执行后退语句。这时语句1当时执行过程中进栈的 n = 2 需要出栈,从语句1后面开始继续执行。执行到语句2时,再次重新进入本函数,此时 n=1 ,进入语句1再次被return到语句1后面。再次进入语句2同样被return到语句2后面。然后执行后退语句,此时 n=1 。此时语句2执行过程中进栈的 n=2 需要出栈,从语句2后面开始执行,即后退语句。
这就是整个程序执行的过程。
从以上例子可以看出,在程序执行过程中,print()语句可以帮助我们更好的了解程序的执行过程。

代码附上:

import turtle

def fd(t, length):
    t.fd(length)

def lt(t, angle):
    t.lt(angle)

def bk(t, length):
    t.bk(length)

def rt(t, angle):
    t.rt(angle)

def draw(t, length, n):
    if n == 0:
        return
    print("%d beginning" %n) # execute from beginning or not
    angle = 50 
    fd(t, length*n)
    lt(t, angle)
    print(n)  # watch the number of n
    draw(t, length, n-1)
    print("first_draw") # first recurtion function
    print(n) # watch the number of n
    rt(t, 2*angle)
    draw(t, length, n-1)
    print("second_draw") # second recursion function
    lt(t, angle)
    bk(t, length*n)
    print("bk and %d" %n) # watch bk and the number of n 

def main():
    bob = turtle.Turtle()
    bob.pensize(4)
    bob.speed(1)

    draw(bob, 100, 2)

main()

版权声明:本文为suqi791776原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。