【发布时间】:2015-03-30 11:05:05
【问题描述】:
出于教育目的,我希望能够打印当前函数的 complete 调用表达式。不一定来自异常处理程序。
经过一番研究,我最终得到了这段非常简单的代码:
import inspect
import linecache
def print_callexp(*args, **kwargs):
try:
frame = inspect.currentframe()
# method 1, using inspect module only
print(inspect.getframeinfo(frame.f_back).code_context)
# method 2, just for the heck of it
linecache.checkcache(frame.f_code.co_filename)
line = linecache.getline(
frame.f_back.f_code.co_filename,
frame.f_back.f_lineno,
frame.f_back.f_globals)
print(line)
# there's probably a similar method with traceback as well
except:
print("Omagad")
a_var = "but"
print_callexp(a_var, "why?!", 345, hello="world")
结果:
[' print_callexp(a_var, "why?!", 345, hello="world")\n']
print_callexp(a_var, "why?!", 345, hello="world")
它完全符合我的要求,只要调用表达式位于一行上。但是多行表达式只会得到最后一行,显然需要我更深入地挖掘调用上下文。
# same example but with a multiple lines call
a_var = "but"
print_callexp(
a_var, "why?!", 345, hello="world")
这给了我们:
[' a_var, "why?!", 345, hello="world")\n']
a_var, "why?!", 345, hello="world")
如何正确打印完整的调用表达式?
“使用 lineno 值并应用一些 regex/eval 技巧”不是可接受的答案。我更喜欢更清洁的东西。我不介意导入更多模块,只要它们是 Python 3.x 标准库的一部分。但尽管如此,我会对任何参考资料感兴趣。
【问题讨论】:
-
不确定python开发团队是否解决了这个问题。当我对代码中的异常进行故障排除时,它们通常只引用多行函数调用的最后一行。尝试的一种选择可能是遍历 lineno,并评估响应,直到没有抛出语法错误/异常。
-
@Jonathan Yep... 是这样想的,因此问题的最后一点:)
-
这不是一个简单的问题要解决。您可以尝试将调用 file 解析为 AST tree,但表达式的哪一部分是调用者?例如,Python 允许广泛的动态调用约定。
-
我会接受 Martijn 对 AST 的建议,只打印第 N 行的整个语句。你可能会得到一个完整的缩进块,但打印太多总比太少好。
-
IPython 只打印几行上下文; 2 之前和 2 之后,或类似。
标签: python debugging python-3.x introspection