gpt4 book ai didi

python - 逐行记录函数执行的装饰器

转载 作者:太空狗 更新时间:2023-10-29 19:25:35 31 4
gpt4 key购买 nike

我正在编写一个需要几分钟才能运行的脚本,并希望向用户提供一些有关其进度的输出。不幸的是我非常懒惰。我想做的是编写一个没有日志记录的函数,然后对其应用一个装饰器,该装饰器逐步执行该函数并在执行该行之前打印每一行。基本上我正在寻找的是一个 loggingdecorator 这样的:

>>> @loggingdecorator
... def myfunction():
... foo()
... bar()
... baz()
>>> myfunction()
Starting myfunction
foo() ... [OK]
bar() ... [OK]
baz() ... [OK]
myfunction Done!

这是我到目前为止尝试过的:

import sys


def logging_tracer(frame, event, arg):
def local_tracer(local_frame, event, arg):
if frame is local_frame:
print frame.f_code.co_name, event, arg

print frame.f_code.co_name, event, arg
return local_tracer


def loggingdecorator(func):
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

不幸的是,这打印得太多了;它遵循函数调用并逐行打印出来(好吧,这实际上并没有打印源代码行,使用检查的现有答案,结合跟踪函数中框架对象上的东西就可以了),但我我对 logging_tracer 的方式有点困惑,除非所讨论的函数实际上已被装饰。

最佳答案

这就是我想出的。 @Corley Brigman的评论让我开始朝着正确的方向前进。这有点 hackey,sys.gettrace/settrace 被明显地记录为“CPython 实现细节”,因此不应期望此解决方案在其他实现中起作用。也就是说,它似乎很有效。 cpython 中的跟踪功能不提供任何“行已完成执行”的通知,因此我的问题中的 [ok] 没有任何意义。

修复递归跟踪问题只是一个简单的问题,即保留被装饰的函数的缓存,然后仅当被跟踪的帧来自被装饰的函数时才产生输出。

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

关于python - 逐行记录函数执行的装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19227636/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com