2012-07-06 216 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都會返回給你的調用者一些東西,而不管你調用的函數是否與你所在的函數相同。