2014-11-24 18 views
1

我想在異常期間找出所有「調用」堆棧幀中的所有活動變量。在異常期間檢索所有堆棧幀中的所有活動變量

例如,請考慮下面的例子來說明異常滲出高達callClient場景

import time 

def mainFunc(): 
    now = time.time() 
    author = "me" 
    callClient() 

def callClient(): 
    message = "Hello, World!" 
    to = "stackoverflow.com" 
    callNoOp() 
    callException() 

def callNoOp(): 
    subject = "Question in stack trace" 
    print "No-op" 

def callException(): 
    question = "What do I do?" 
    raise Exception("Vishwanathan, vellai vendum!") 

mainFunc() 

。我想看看那個時候所有的活動變量。 locals()會幫助我這種要求。

我還想知道的是messageto在​​3210的值。而異常發生時的值爲question

我已經通過了traceback module docs。它似乎打印堆棧跟蹤,但不是在這些堆棧幀中激活的變量。

+0

你爲什麼要調用一個函數來引發異常?如果你從'callClient'提出它,你就可以很容易地在追蹤中包含'to'和'message'。你能否提供一個你想要做的不太抽象的例子? – jonrsharpe 2014-11-24 09:31:08

+0

我試圖說明我最近面臨的情況。最近繼承了一個代碼,沒有在多個地方失敗的文檔。我沒有授權對代碼進行大的修改,以免在這個高流量的季節變得不穩定。我只依靠日誌。我想用更多的數據填充日誌,這可以幫助我進行調試。喬恩,你會考慮取消倒票嗎? – Sriram 2014-11-24 09:42:25

+1

@jonrsharpe:可能會產生一個示例回溯。 – 2014-11-24 09:43:04

回答

1

我已經能夠找到暫時的解決方法,它看起來像這樣。

def mainFunc(): 
    now = time.time() 
    author = "me" 
    try: 
     callClient() 
    except: 
     tb = sys.exc_info()[2] 
     while tb: 
      print tb.tb_lineno, "@", tb.tb_frame.f_locals 
      tb = tb.tb_next 
2

回溯包含一個對象鏈,通過tb_next屬性鏈接在一起。每個追溯對象還通過tb_frame鏈接到該幀,並且每個幀都有一個f_locals屬性。

給出一個回溯的對象,就可以打印所有當地人沿鏈:

current = traceback 
while current is not None: 
    print current.tb_frame.f_locals 
    current = current.tb_next 

見Python的數據模型的Standard type hierarchy section(向下滾動到回溯對象)。

你也可以看看的inspect.trace() utility function,其中解包鏈到一個名爲元組序列:

import inspect 

for frame_info in inspect.trace(): 
    print frame_info[0].f_locals 

一定要確保你清楚地回溯明確的任何引用;因爲回溯包含對當前名稱空間的引用,所以在此處創建循環引用幾乎是微不足道的。最好的做法是延遲清除這些引用,最糟糕的情況是一個帶有__del__方法的對象參與了這個循環,然後垃圾收集永遠不會破壞那個循環,並且你有內存泄漏。

+0

非常感謝Martijn。我在黑暗中射箭,能夠找到類似於你的解決方案的東西(我也在下面發佈了我的發現)。我打算提高你的答案。 – Sriram 2014-11-24 09:45:52