在C/C++中,我经常发现在调试时定义一个宏很有用,比如ECHO(x),它打印出变量名和它的值(即ECHO(variable)可能打印variable 7)。如here所述,您可以使用'stringification‘运算符#在宏中获取变量名。有没有办法在Python中做到这一点?
换句话说,我想要一个函数
def echo(x):
#magic goes here如果被调用为foo=7; echo(foo) (或许是foo=7; echo('foo') ),它将输出foo 7。我意识到,如果我将变量和它的名称都传递给函数,这样做是微不足道的,但我在调试时经常使用这样的函数,而且重复总是会激怒我。
发布于 2012-01-14 03:50:18
不是真正的解决方案,但可能很方便(无论如何,您有问题的echo('foo') ):
def echo(**kwargs):
for name, value in kwargs.items():
print name, value
foo = 7
echo(foo=foo)更新:针对使用inspect的echo(foo)的解决方案
import inspect
import re
def echo(arg):
frame = inspect.currentframe()
try:
context = inspect.getframeinfo(frame.f_back).code_context
caller_lines = ''.join([line.strip() for line in context])
m = re.search(r'echo\s*\((.+?)\)$', caller_lines)
if m:
caller_lines = m.group(1)
print caller_lines, arg
finally:
del frame
foo = 7
bar = 3
baz = 11
echo(foo)
echo(foo + bar)
echo((foo + bar)*baz/(bar+foo))输出:
foo 7
foo + bar 10
(foo + bar)*baz/(bar+foo) 11它有最小的调用,但它对换行符敏感,例如:
echo((foo + bar)*
baz/(bar+foo))将打印:
baz/(bar+foo)) 11发布于 2012-01-14 03:28:30
def echo(x):
import inspect
print "{0}: {1}".format(x, inspect.stack()[1][0].f_locals[x])
y = 123
echo('y')
# 'y: 123'另请参阅:https://stackoverflow.com/a/2387854/16361
请注意,这可能会导致GC问题:
http://docs.python.org/library/inspect.html#the-interpreter-stack
它还会让那些因摆弄镜框而被灼伤的人拒之门外,并可能在你的嘴里留下难闻的味道。但它会起作用的。
发布于 2012-01-14 03:29:29
这里有一个解决方案,你可以输入更多的内容来调用它。它依赖于locals内置函数:
def print_key(dictionary, key):
print key, '=', dictionary[key]
foo = 7
print_key(locals(), 'foo')使用inspect模块也可以生成具有您提到的语义的echo。但是,请务必阅读inspect文档中的警告。这是一个丑陋的、不可移植的技巧(它并不适用于Python的所有实现)。请确保仅将其用于调试。
其思想是查看调用函数的locals。inspect模块只允许:调用由f_back属性链接在一起的frame对象表示。每个帧的局部变量和全局变量都是可用的(也有内置变量,但您不太可能需要打印它们)。
您可能希望显式删除任何引用框架对象,以防止引用循环,如inspect docs中所述,但这并不是绝对必要的-垃圾收集迟早会释放它们。
import inspect
def echo(varname):
caller = inspect.currentframe().f_back
try:
value = caller.f_locals[varname]
except KeyError:
value = caller.f_globals[varname]
print varname, '=', value
del caller
foo = 7
echo('foo')https://stackoverflow.com/questions/8855974
复制相似问题