我不时会在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重建异常以获得更多上下文,这非常简单,可能是正确的选择。当你有多个级别的泛型函数时会有点棘手,但这当然有可能处理。
关于如何实现这一目标的任何其他想法?我是否想念一些更改堆栈框架名称的简单方法?
编辑: 添加示例回溯,显示相对无用的回溯:
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 :(得分: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
>>>