在日常情况,可能会涉及到一个数据模型,就是前两个数字相加的所得之和,等于第三个数字,这里我们可以引用斐波拉数列数据模型;例如有如下数字

0,1,1,2,3,5,13,13,21,34,55,144,233,377,610

#打印出如上述数列,前两个数相加等于后面的数(这里做一个限制条件如果arg3>10,则返回arg3,否则就是一个无限制的循环)

#顶一个函数func

def func(arg1,arg2):
  if arg1 == 0:
    pass
  arg3 = arg1 + arg2
  if arg3 >10:
  return arg3
  func(arg2,arg3)
result = func(0,1)
print result


运行结果如下:

None


对上述代码进行剖析,我们先看如下代码:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = 'ryan'

def fun5():
    return 13
    
def fun4():
    fun5():
def fun3():
    fun4()
    
def fun2():
    fun3()
    
def fun1():
    fun2()
    
result =fun1()
print result

该代码是一个函数调用另外一个函数的例子,运行该代码,结果如下:

None

即result的结果为None,该代码中所有的地方都是函数,最后的定义是将函数func1()赋给变量result,输出变量为None时,说明函数func1没有返回值,或者定义返回值为None,由上述代码可以发现func1没有定义返回值None,所以默认返回None;所以对该代码解释如下:

当我们执行result=func1()时,func1就会执行如下代码:

def fun1():
   fun2()

当执行完def func1()就会执行func2(),而func2内容如下:

def fun2():
   fun3()

同样,当执行完def func2():就会再执行func3(),如果func2中有返回值,则此返回值就返回给调用它的函数func1

同样再去执行func3(),即:

def fun3():
   fun4()

接着执行func4(),即:

def fun4():
   fun5()

而函数func5代码如下:

def func5():

  return 13

从以上代码可以发现,在func4()调用func5的时,func5会返回一个数字13,该值是函数func5的返回值,该返回值会赋给调用他的函数,这里调用func5的函数时func4,所以此时func4里的func5其实就是return 13 语句返回的结果,即13的结果,所以func4有一个数字13(返回值 13),即:

def func4():                            def func4():
   func5() ======================================>     13

此时的func4并没有返回值,所以实际代码为:

def func3():
   func4

故此次调用也就没有返回值,由于func3没有返回值,所以后面的func2调用也就没有返回值,所以上述最终结果为None

所以代码的实质为:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

def fun5():
    return 13
    
def fun4():
    ret = fun5():
    #return None
#因为func4默认没有返回值,即返回值为None,所以13到达这一步就停止了继续传递了,

def fun3():
    fun4()
    #return None   
#此处func3获取func4的返回值None

def fun2():
    fun3()
    #return None
 
#此处func2获取func3的返回值None  

def fun1():
    fun2()
    #return None

#此处func1获取func2的返回值None   
#resut=func1(),即result等于func1的返回值None,所以输出None
result =fun1()
print result

要实现该代码返回值,只需要做如下修改即可:


#!/usr/bin/env python
# -*- coding:utf-8 -*-

def fun5():
    return 13
    
def fun4():
    ret = fun5():
    #return None
    return ret
#因为func4默认没有返回值,即返回值为None,所以13到达这一步就停止了继续传递了,

def fun3():
    return fun4()
    #return None   
#此处func3获取func4的返回值None

def fun2():
    return fun3()
    #return None
 
#此处func2获取func3的返回值None  

def fun1():
    retrun fun2()
    #return None

#此处func1获取func2的返回值None   
#resut=func1(),即result等于func1的返回值None,所以输出None
result =fun1()
print result

解释:func5有返回值13,在func4中我们赋给了变量ret = func5(),所以ret=13,然后在后面加一句return ret,这样func4返回值即return ret 返回结果,即13,而func3下调用的func4,所以只需要在func3下将func4()改为return func4()就可以实现func3有返回值,同样在func2下调整fun3()为return func3()是func2具备返回值,再最后的func1中将func2()改为return func2()这样func1就有返回值,该过程的实质就是讲func5中的return 13经过传递最终传递到func1,从而输出出来。所以运行以上代码结果为:

13

所以再回过头来看第一次的代码:

def func(arg1,arg2):
  if arg1 == 0:
    pass
  arg3 = arg1 + arg2
  if arg3 > 10:
    return arg3
  return func(arg2,arg3)
result = func(0,1)
print result


输出结果为:

13

解释:将0,1放进函数内进行执行:

arg1=0,arg2=1,arg3 = 0 + 1=1,

当执行到if语句时,就不会继续执行,因为此时的arg3<10,所以执行下面的func(arg2,arg3)语句此时func(arg2,arg3)为func(1,1),arg2=1,arg3=1,即func(1,1),arg3=1+1=2,arg3<10,

继续执行

func(arg2,arg3),arg2=1,arg3=2,即func(arg1=1,arg2=2),arg3=1+2=3,arg3<10,

继续执行

func(arg2,arg3),arg2=2,arg3=3,即func(arg1=2,arg2=3),arg3=arg1+arg2=2+3=5,arg3<10,

继续执行

func(arg2,arg3),arg2=3,arg3=5,即func(arg1=2,arg2=5),arg3 =arg1+arg2=3+5=8,arg3<10,

继续执行

func(arg2,arg3),arg2=5,arg3=13,即func(arg1=5,arg2=13),arg3=arg1+arg2=5+8=13,arg3>10,

此时返回arg3,即13,if语句成立后,运行return arg3,此时只是在arg3>10时作为本次调用结果返回,但是我们要求的本次返回的结果要返回给上一次调用,才可以正常输出否则结果显示为None,这里可以参考上面的fun1.....fun5函数的例子理解,所以在最后要有一次要将结果赋值给上次调用,这里可以将代码再做修改看下进行分析:

def func(arg1,arg2):
    if arg1 == 0:
        pass
    arg3 = arg1 +arg2
    #print arg3
    if arg3 >10:
        return arg3
    print arg3
    print "###########"
    return func(arg2,arg3)
result =func(0,1)
print result

运行结果:

1
###########
2
###########
3
###########
5
###########
8
###########
13

如果将return func(arg2,arg3)改为func(arg2,arg3)再看下运行结果:

def func(arg1,arg2):
    if arg1 == 0:
        pass
    arg3 = arg1 +arg2
    #print arg3
    if arg3 >10:
        return arg3
    print arg3
    print "###########"
    func(arg2,arg3)
result =func(0,1)
print result

运行结果:

1
###########
2
###########
3
###########
5
###########
8
###########
None


从这里可以看出当arg3<10的时候,都可以输出的arg3,而当arg3>10的时并没有arg3的值输出,其根本原因是没有将arg3返回给func函数体,即arg3的值就停留在return arg3这里,没有进一步传递,因为是递归调用,本次的返回值应该返回给上次调用的函数体本身,即func(arg),所以此时的返回值却停留在return arg3这里,所以返回值为默认值(即None),故这里应该在func(arg2,arg3)前面添加return


def func(arg1,arg2):
    if arg1 == 0:
        pass
    arg3 = arg1 +arg2
    #print arg3
    if arg3 >10:
        return arg3
    print arg3
    print "###########"
    return func(arg2,arg3)
result =func(0,1)
print result