2009-10-30 33 views
1

我可以獲取在回溯中調用的最後一個函數的參數嗎?怎麼樣?從回溯中獲取最後一個函數的調用參數?

我想製作一個標準錯誤捕捉器來製作可讀的代碼,但是卻向用戶提供了詳細的信息。

在以下示例中,我希望GET_PARAMS向我返回提供給os.chown的參數元組。檢查由Alex Martelli建議的inspect模塊,我找不到那個模塊。

def catch_errors(fn): 
    def decorator(*args, **kwargs): 
     try: 
      return fn(*args, **kwargs) 
     except (IOError, OSError): 
      msg = sys.exc_info()[2].tb_frame.f_locals['error_message'] 
      quit(msg.format(SEQUENCE_OF_PARAMETERS_OF_THE_LAST_FUNCTION_CALLED)\ 
      + '\nError #{0[0]}: {0[1]}'.format(sys.exc_info()[1].args), 1) 
    return decorator 

@catch_errors 
def do_your_job(): 
    error_message = 'Can\'t change folder ownership \'{0}\' (uid:{1}, gid:{2})' 
    os.chown('/root', 1000, 1000) # note that params aren't named vars. 

if __name == '__main__' and os.getenv('USERNAME') != 'root': 
    do_your_job() 

(感謝Jim Robert用於裝飾)

+2

你的除外應該是「除(IOError,OSError):」。就目前而言,您只捕獲IOError,然後將異常實例分配給OSError。 – jamessan 2009-10-30 16:34:46

+0

糟糕。謝謝,詹姆斯。 – 2009-10-30 17:56:21

回答

0

與使用裝飾爲你想達到什麼樣的問題是,異常處理程序獲取框架是do_your_job() S,不os.listdir() S,os.makedirs() S或os.chown()秒。所以你要打印的信息是do_your_job()的參數。爲了獲得我認爲你打算的行爲,你必須修飾你所調用的所有庫函數。

5

對於這樣的檢驗任務,總以爲在標準庫中第一個模塊inspect的。這裏,inspect.getargvalues給出了給定幀的參數值,inspect.getinnerframes給出了來自回溯對象的感興趣幀。

+0

+1馬爾泰利教我另一件我不知道的事情。 – Yarin 2012-07-26 00:18:13

3

這裏是和這樣的功能的例子一些問題,你不能得到解決:

import sys 

def get_params(tb): 
    while tb.tb_next: 
     tb = tb.tb_next 
    frame = tb.tb_frame 
    code = frame.f_code 
    argcount = code.co_argcount 
    if code.co_flags & 4: # *args 
     argcount += 1 
    if code.co_flags & 8: # **kwargs 
     argcount += 1 
    names = code.co_varnames[:argcount] 
    params = {} 
    for name in names: 
     params[name] = frame.f_locals.get(name, '<deleted>') 
    return params 


def f(a, b=2, c=3, *d, **e): 
    del c 
    c = 4 
    e['g'] = 6 
    assert False 

try: 
    f(1, f=5) 
except: 
    print get_params(sys.exc_info()[2]) 

輸出是:

{'a': 1, 'c': 4, 'b': 2, 'e': {'g': 6, 'f': 5}, 'd':()} 

我沒用過inspect.getinnerframes()展現另一種方式得到需要的框架。雖然它稍微簡化了一些,但它也會做一些你不需要的額外工作,但速度相對較慢(inspect.getinnerframes()爲回溯中的每個模塊讀取源文件;這對調試調用並不重要,但在其他情況下可能是問題)。

+0

我不明白:什麼是慢 - 檢查或你的方式? – 2009-10-31 11:04:51

+0

似乎只有在函數內引發異常時,您的代碼纔有效。 – 2009-10-31 11:21:12

相關問題