本着调试的精神,我提出我的hax:
import re
import inspect
assignment_regex = re.compile(r'(\s*)([\w\d_]+)\s*=\s*[\w\d+]')
def show_guts(fn):
source = inspect.getsource(fn)
lines = []
for line in source.split('\n'):
if 'show_guts' in line:
continue
lines.append(line)
if 'def' in line:
# kwargs will match the regex
continue
search = assignment_regex.search(line)
try:
groups = search.groups()
leading_whitespace = groups[0]
variable_name = groups[1]
lines.append(leading_whitespace + 'print "Assigning {0} =", {0}'.format(variable_name))
except AttributeError: # no match
pass
new_source = '\n'.join(lines)
namespace = {}
exec new_source in namespace
fn = namespace[fn.__name__]
def wrapped(*args, **kwargs):
arg_string = ', '.join(map(str, args))
kwarg_string = ', '.join(key + '=' + str(value) for key, value in kwargs.iteritems())
print "Calling", fn.__name__ + '(' + ', '.join((arg_string, kwarg_string)) + ')'
return fn(*args, **kwargs)
return wrapped
基本上,这会自动执行您正在执行的操作。它获取传入函数的源代码,遍历源代码中的每一行,并为每个赋值语句创建一个新的打印语句并将其附加到源代码主体。编译新的源代码并将函数替换为新编译的函数。然后为了获得*args 和**kwargs,我创建了普通的装饰器包装函数并输入了一些不错的打印语句。在inspect 模块的帮助下,这部分可能会好一些,但是whatevs。
foo() -> 带有打印语句的 foo()
# This...
@show_guts
def complicated(a, b, keyword=6):
bar = str(a)
baz = str(b)
if a == b:
if keyword != 6:
keyword = a
else:
keyword = b
return bar + baz
# becomes this
def complicated(a, b, keyword=6):
bar = str(a)
print "Assigning bar =", bar
baz = str(b)
print "Assigning baz =", baz
if a == b:
if keyword != 6:
keyword = a
print "Assigning keyword =", keyword
else:
keyword = b
print "Assigning keyword =", keyword
return bar + baz
用法
@show_guts
def foo(a, b):
bar = str(a)
baz = str(b)
return bar + baz
@show_guts
def complicated(a, b, keyword=6):
bar = str(a)
baz = str(b)
if a == b:
if keyword != 6:
keyword = a
else:
keyword = b
return bar + baz
foo(1, 2)
complicated(3, 4)
complicated(3, 3)
complicated(3, 3, keyword=123)
输出
Calling foo(1, 2, )
Assigning bar = 1
Assigning baz = 2
Calling complicated(3, 4, )
Assigning bar = 3
Assigning baz = 4
Assigning keyword = 4
Calling complicated(3, 3, )
Assigning bar = 3
Assigning baz = 3
Calling complicated(3, 3, keyword=123)
Assigning bar = 3
Assigning baz = 3
Assigning keyword = 3
我可能在正则表达式中遗漏了一些极端情况,但这会让你接近。