2012-07-06 182 views
20

我刚开始学习蟒蛇(V3.2.3)也碰到了关于此功能的return一个奇怪的问题:返回递归函数

def test(x): 
    if x > 9 : 
     test(x - 10) 
    else: 
     print('real value',x) 
     return x 

x = int(input()) 
y = test(x) 
print('this should be real value',y) 

当我运行它,我得到:

45 
real value 5 
this should be real value None 

但我预计:

45 
real value 5 
this should be real value 5 

我尝试添加return xif,我得到了默认的输入值。任何人都可以请解释return是如何工作的?

+3

它与非递归调用完全相同:如果要从您调用的函数传播返回值,则必须使用'return'关键字自己执行此操作。调用一个函数会产生它的返回值,但这取决于你使用该返回值做些什么,无论被调用的函数是否递归。 – 2012-07-06 06:23:21

回答

13

返回值是缩进的,所以它只在else分支中执行。如果第一个分支被采用,则该函数隐式返回None。

你需要改变这

return test(x-10) 
+0

那么这是否意味着即使假条件不成立,我也需要返回? – 2012-07-06 06:22:33

+1

@AlexKey:是的。由于'y'只被分配了第一个函数调用的值。这不是Python独有的东西。 Python独有的唯一部分是函数在没有返回语句时隐式返回None。 – 2012-07-06 07:08:02

4

你忘了返回值时x > 9。没有返回值,该函数将“返回”None

+0

所以总结我需要把这两个条件的回报是吗? – 2012-07-06 06:19:14

+0

@AlexKey:在上面的代码中,是的,您将返回评估'test(x - 10)'的值 – nhahtdh 2012-07-06 07:51:13

34

您调用test(45)。这测试是否为45 > 9,这是真的,所以它调用test(35)(45 - 10),而不返回结果。同样的事情发生在test(25)test(15)之间,直到最后调用test(5)

这会打印“真实值5”,然后返回5.但是,从函数返回的结果始终为将其返回给此函数的直接调用方。它不会立即通过多次呼叫跳出;毕竟,调用者可能想要在返回结果之前对返回的结果进行一些操作,然后返回这是调用者。但在这种情况下,只有test(5)返回任何东西;所有其他人呼叫test(x - 10),等待它返回,忽略它返回的内容,然后(隐式地)返回None。由于最外面的调用test(45)就是这些情况之一,所以你得到的是None

这里在发生什么可视化的尝试:

test(45): 
| test(35): 
| | test(25): 
| | | test(15): 
| | | | test(5): 
| | | | | print('real value',5) 
| | | | | return 5 to test(15) 
| | | | return None to test(25) 
| | | return None to test(35) 
| | return None to test(45) 
| return None 

你没有在解释称test(5)test(5)从另一个函数调用内部调用。所以从test(5)返回到那功能调用。这是一个自己调用函数的事实是完全不相关。你会得到完全相同的结果,如果你的代码是这样的:

def test45(x): 
    if x > 9 : 
     test35(x - 10) 
    else: 
     print('real value',x) 
     return x 

def test35(x): 
    if x > 9 : 
     test25(x - 10) 
    else: 
     print('real value',x) 
     return x 

def test25(x): 
    if x > 9 : 
     test15(x - 10) 
    else: 
     print('real value',x) 
     return x 

def test15(x): 
    if x > 9 : 
     test5(x - 10) 
    else: 
     print('real value',x) 
     return x 

def test5(x): 
    if x > 9 : 
     print 'No more tests :(' 
    else: 
     print('real value',x) 
     return x 

测试(x)函数你“X = 45”调用是一样的调用test45(45)。我希望你能明白为什么很显然None应该返回,当递归不是涉及。那么,当涉及递归时,没有任何变化。 return声明既不知道也不关心它是否从递归调用的函数返回,它在任何情况下的行为都完全相同。

事实上,递归并不是什么“特殊”的东西;它的行为与普通函数调用的方式完全相同。你从通过参数调用你的东西获得信息,并且通过返回信息将信息返回给调用你的东西。如果你没有返回任何东西(可能只有在if的一个分支中),那么无论你是否调用该分支中的任何其他函数,无论该函数可能返回什么,如果你打电话,None都会返回给你的调用者一些东西,而不管你调用的函数是否与你所在的函数相同。