2015-12-06 89 views
4

documentation如何獲取Python解釋器堆棧的當前深度?

sys.getrecursionlimit()

返回的遞歸限制的當前值,Python解釋堆棧的最大深度。此限制可防止無限遞歸 導致C堆棧溢出並導致Python崩潰。它可以是由setrecursionlimit()設置的 。

我正在酸洗一個物體時遇到了遞歸限制。我正在酸洗的對象只有幾層嵌套,所以我對所發生的事情感到有點困惑。

我已經能夠與下面的技巧來規避這個問題:

try: 
    return pickle.dumps(x) 
except: 
    try: 
     recursionlimit = getrecursionlimit() 
     setrecursionlimit(2*recursionlimit) 
     dumped = pickle.dumps(x) 
     setrecursionlimit(recursionlimit) 
     return dumped 
    except: 
     raise 

測試在不同的背景下上面的代碼中有時會導致第一try成功,有時它會導致成功在第二try 。到目前爲止,我還沒有能夠使raise成爲例外。

爲了進一步調試我的問題,有一種方法可以獲得堆棧的當前深度。這將允許我驗證進入的堆棧深度是否確定上面的代碼片段是否會在第一個try或第二個代碼塊上成功。

標準庫是否提供了獲取堆棧深度的函數,如果沒有,我該如何獲取它?

def get_stack_depth(): 
    # what goes here? 
+2

這聽起來像一個XY問題。與其理解如何繞過遞歸限制,您應該嘗試弄清楚爲什麼要觸及它。 – IanAuld

+0

@IanAuld確實。這正是我想要做的,我試圖看看問題是否取決於在進行違規調用時的堆棧深度。要做到這一點,我需要弄清楚如何獲取堆棧的當前深度。 –

+1

如果你能提供你在獲取/設置限制之間做的事情,那會更好......至少是一個原型版本。這樣我們可以用它來破解... – Aftnix

回答

6

您可以從inspect.stack()看到整個調用堆棧,所以目前採取深度將是len(inspect.stack())

在另一方面,我猜你得到了完整的堆棧打印出來的時候「最大遞歸深度超過」異常發生。該堆棧跟蹤應該顯示你到底發生了什麼問題。

+0

謝謝,'len(inspect.stack())'正是我所期待的。 –

1

如果速度有問題,繞過檢查模塊的速度會更快。

def get_stack_size(): 
    """Get stack size for caller's frame. 

    %timeit len(inspect.stack()) 
    8.86 ms ± 42.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 
    %timeit get_stack_size() 
    4.17 µs ± 11.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each) 
    """ 
    size = 2 # current frame and caller's frame always exist 
    while True: 
     try: 
      sys._getframe(size) 
      size += 1 
     except ValueError: 
      return size - 1 # subtract current frame