gpt4 book ai didi

python - 打印函数的局部变量名称和值

转载 作者:太空狗 更新时间:2023-10-29 21:34:28 24 4
gpt4 key购买 nike

为了帮助我调试我编写的一些代码,我想制作一个函数装饰器,在创建或修改每个变量时打印出变量的名称及其值,本质上是给我一个“逐个播放” "查看我调用该函数时发生的情况。

到目前为止,我一直使用的方法是在我想查看发生了什么的地方简单地添加一行类似 print(foo) 的代码,但这非常耗时并且使我的代码看起来很乱(可能是非 Pythonicness 的缩影)。

实际上我想做的是:

@show_guts
def foo(a,b):
biz = str(a)
baz = str(b)
return biz + baz

foo("banana","phone")

在 IDE 中打印如下内容:

biz = "banana"
baz = "phone"
bananaphone

我的问题是 @show_guts 会是什么样子。我知道可以使用像

这样的装饰器只打印 ab 的值
def print_args(function):
def wrapper(*args,**kwargs):
print("Arguments:",args)
print("Keyword Arguments:",kwargs)
return function(*args,**kwargs)
return wrapper

这给了我

Arguments: ('banana', 'phone')
Keyword Arguments: {}
'bananaphone'

但我完全不知道如何打印局部变量名称及其值。更不用说以“整洁”的方式进行了。

最佳答案

如果不启用跟踪,您将无法执行此操作;这会损害性能。函数局部变量在函数被调用时构造,并在函数返回时清除,因此没有其他方法可以从装饰器访问这些局部变量。

您可以使用 sys.settrace() 插入跟踪函数,然后响应 Python 解释器发送给该函数的事件。我们要做的是跟踪只是装饰函数,并在函数返回时记录局部变量:

import sys
import threading

def show_guts(f):
sentinel = object()
gutsdata = threading.local()
gutsdata.captured_locals = None
gutsdata.tracing = False

def trace_locals(frame, event, arg):
if event.startswith('c_'): # C code traces, no new hook
return
if event == 'call': # start tracing only the first call
if gutsdata.tracing:
return None
gutsdata.tracing = True
return trace_locals
if event == 'line': # continue tracing
return trace_locals

# event is either exception or return, capture locals, end tracing
gutsdata.captured_locals = frame.f_locals.copy()
return None

def wrapper(*args, **kw):
# preserve existing tracer, start our trace
old_trace = sys.gettrace()
sys.settrace(trace_locals)

retval = sentinel
try:
retval = f(*args, **kw)
finally:
# reinstate existing tracer, report, clean up
sys.settrace(old_trace)
for key, val in gutsdata.captured_locals.items():
print '{}: {!r}'.format(key, val)
if retval is not sentinel:
print 'Returned: {!r}'.format(retval)
gutsdata.captured_locals = None
gutsdata.tracing = False

return retval

return wrapper

演示:

>>> @show_guts
... def foo(a,b):
... biz = str(a)
... baz = str(b)
... return biz + baz
...
>>> result = foo("banana","phone")
a: 'banana'
biz: 'banana'
b: 'phone'
baz: 'phone'
Returned: 'bananaphone'

关于python - 打印函数的局部变量名称和值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24165374/

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