2011-08-16 123 views
13

我有一個問題關於從Python文檔sys.setrecursionlimit()Python的最大遞歸,約sys.setrecursionlimit問題()

此功能:

設置Python解釋器的最大深度堆棧來限制。此限制可防止無限遞歸導致C堆棧溢出並導致Python崩潰。 儘可能高的限制取決於平臺。當用戶需要深度遞歸的程序和支持更高限制的平臺時,用戶可能需要將限制設置得更高。這應該謹慎處理,因爲太高的限制可能會導致崩潰。

這裏是我的問題:

讓我們這個沒用的遞歸函數:

def rec(N): 
    if N==0: 
     return 1 
    else: 
     return rec(N-1); 

現在讓我們來設置最大遞歸100:

sys.setrecursionlimit(100) 

如果我嘗試rec(99)(100遞歸調用),我得到:

RuntimeError: maximum recursion depth exceeded 

要計算rec(99)我需要將遞歸限制設置爲105

這是爲什麼?

回答

13

它名字很差。它應該說Stack Depth,而不是遞歸深度。遞歸意味着它是一次又一次的一次又一次的限制。實際上,你可以擁有實際的代碼,只需要調用100個深度。我不會推薦它,但你可以。他們可以避開它,因爲在現實世界中,你遇到這種情況的唯一時間就是遞歸。當你因此而崩潰時,看到「遞歸」這個詞給你提供了一個直觀的線索,而不是「堆棧」。但是,說實話,你的代碼剛剛崩潰,你想要一個相關的錯誤信息,對嗎?99.99999%的時間告訴你你弄錯了什麼(你錯過了你的遞歸基例))

+0

Thx,我想我應該仔細閱讀定義,而不是看功能的名稱 –

4

Python運行時還需要進行函數調用才能訪問函數。

4

它基於TOTAL堆棧深度,而不是任何特定單一函數的深度。當您第一次調用rec()時,您可能已經處於堆棧深度5。

以5個遞歸函數爲例。每個進行98次遞歸調用,最後一次調用下一個遞歸函數。如果遞歸限制爲100,您是否確實希望允許每個遞歸函數爲總共500個調用深度創建99個調用?不,這可能會使譯員在這些深處崩潰。

因此,遞歸限制是全局所有函數的最大深度,而不是任何單個命名函數。