<p>这就是我的想法。<a href="https://stackoverflow.com/users/349948/corley-brigman">@Corley Brigman</a>的评论让我有了正确的开始。这有点骇人听闻,<code>sys.gettrace/settrace</code>被很快地记录为“CPython实现细节”,因此不应期望此解决方案在其他实现中起作用。这就是说,看起来效果不错。cpython中的跟踪功能没有提供任何“line finished executing”的通知,因此我的问题中的<code>[ok]</code>没有任何意义。在</p>
<p>修复递归跟踪问题只是一个简单的问题,即保留已修饰函数的缓存,然后只在被跟踪的帧来自已修饰的函数时生成输出。在</p>
<pre><code>import inspect
import sys
def logging_tracer(frame, event, arg):
lines, firstline = inspect.getsourcelines(frame)
def local_tracer(local_frame, event, arg):
if event == 'line' and frame is local_frame:
print event, frame.f_lineno,'\t', lines[frame.f_lineno - firstline]
#print event, lines[frame.f_lineno - firstline]
#print frame.f_code.co_name, frame.f_lineno, event, arg
if frame.f_code in LOG_THESE_FUNCTIONS:
print event, frame.f_lineno,'\t', lines[frame.f_lineno - firstline + (event == 'call')]
#print frame.f_code.co_name, event, arg
return local_tracer
else:
return None
LOG_THESE_FUNCTIONS = set()
def loggingdecorator(func):
LOG_THESE_FUNCTIONS.add(func.func_code)
def _wrapper():
old_trace_function = sys.gettrace()
sys.settrace(logging_tracer)
try:
result = func()
except:
raise
else:
return result
finally:
sys.settrace(old_trace_function)
return _wrapper
</code></pre>