2016-02-16 61 views
0

我不時地用Python編寫一個通用函數,它被不同的參數多次調用。通常,這是由其他地方的定義驅動的。動態地改變追蹤/堆棧幀函數的名字

例如:

def issue_sql_query(name, select_stmt): 
    ... 

QUERIES = [ 
    "get_user_rows", "SELECT name, rowid FROM table WHERE type == 'USER';" 
    ... 
] 

results = [] 
for name, select_stmt in QUERIES: 
    results.append((name, issue_sql_query(name, select_stmt))) 

如果有在通用功能(即issue_sql_query或更深的地方)一個例外,我在回溯相對較少的信息,以確定哪一個定義導致錯誤。

我想要做的是動態重命名或增加函數名稱/堆棧幀,以便回溯包括一些識別信息。

將是很好什麼是這樣的:

File "test.py", line 21, in <module> 
    results.append((name, issue_sql_query(select_stmt))) 
File "test.py", line 11, in issue_sql_query(name="get_user_rows") 
    raise RuntimeError("Some error") 
RuntimeError: Some error  

我可以,當然,棒異常處理的通用點,並使用回溯有更多的背景下,這是非常簡單和容易重建異常正確的選擇。當你有多個級別的泛型函數時,它會有點棘手,但這當然是可以處理的。

有關如何完成此任何其他想法?我錯過了一些簡單的方法來更改堆棧幀名稱嗎?

編輯: 添加一個例子回溯呈現出相對不有用回溯:

Traceback (most recent call last): 
    File "C:\Python27\lib\runpy.py", line 162, in _run_module_as_main 
    "__main__", fname, loader, pkg_name) 
    File "C:\Python27\lib\runpy.py", line 72, in _run_code 
    exec code in run_globals 
    File "c:\tmp\report.py", line 767, in <module> 
    main() 
    File "c:\tmp\report.py", line 750, in main 
    charts.append(report.get_chart(title, definition)) 
    File "c:\tmp\report.py", line 614, in get_chart 
    return self.get_bar_chart(title, definition) 
    File "c:\tmp\report.py", line 689, in get_bar_chart 
    definition, cursor, **kwargs)) 
    File "c:\tmp\report.py", line 627, in create_key_table 
    for row in cursor.execute(full_select_stmt): 
sqlite3.OperationalError: near "==": syntax error 
+0

燦你提供了一個錯誤的例子,或者次優回溯? – themantalope

+0

爲什麼你不把'name'作爲參數傳遞給'issue_sql_query()'? – Barmar

+0

Matt,我添加了一個從我的真實代碼中獲得的例子。 –

回答

0

你可以爲每個命名查詢創建包裝功能,使您可以控制引發的異常:

>>> fns = {} 
>>> def issue_sql_query(name, stmt): 
... if name not in fns: 
...  def f(name, stmt): 
...  # run query here 
...  raise Exception(name) 
... 
...  fns[name] = f 
... return fns[name](name, stmt) 
... 
>>> 
>>> issue_sql_query('b', 'SQL') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 9, in issue_sql_query 
    File "<stdin>", line 5, in f 
Exception: b 
>>> issue_sql_query('a', 'SQL') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 9, in issue_sql_query 
    File "<stdin>", line 5, in f 
Exception: a 
>>>