首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何找到传递给函数的变量的名称?

如何找到传递给函数的变量的名称?
EN

Stack Overflow用户
提问于 2012-01-14 03:17:33
回答 3查看 2.2K关注 0票数 9

在C/C++中,我经常发现在调试时定义一个宏很有用,比如ECHO(x),它打印出变量名和它的值(即ECHO(variable)可能打印variable 7)。如here所述,您可以使用'stringification‘运算符#在宏中获取变量名。有没有办法在Python中做到这一点?

换句话说,我想要一个函数

代码语言:javascript
复制
def echo(x):
    #magic goes here

如果被调用为foo=7; echo(foo) (或许是foo=7; echo('foo') ),它将输出foo 7。我意识到,如果我将变量和它的名称都传递给函数,这样做是微不足道的,但我在调试时经常使用这样的函数,而且重复总是会激怒我。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-01-14 03:50:18

不是真正的解决方案,但可能很方便(无论如何,您有问题的echo('foo') ):

代码语言:javascript
复制
def echo(**kwargs):
    for name, value in kwargs.items():
        print name, value

foo = 7
echo(foo=foo)

更新:针对使用inspectecho(foo)解决方案

代码语言:javascript
复制
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))

输出:

代码语言:javascript
复制
foo 7
foo + bar 10
(foo + bar)*baz/(bar+foo) 11

它有最小的调用,但它对换行符敏感,例如:

代码语言:javascript
复制
echo((foo + bar)*
      baz/(bar+foo))

将打印:

代码语言:javascript
复制
baz/(bar+foo)) 11
票数 8
EN

Stack Overflow用户

发布于 2012-01-14 03:28:30

代码语言:javascript
复制
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

它还会让那些因摆弄镜框而被灼伤的人拒之门外,并可能在你的嘴里留下难闻的味道。但它会起作用的。

票数 3
EN

Stack Overflow用户

发布于 2012-01-14 03:29:29

这里有一个解决方案,你可以输入更多的内容来调用它。它依赖于locals内置函数:

代码语言:javascript
复制
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中所述,但这并不是绝对必要的-垃圾收集迟早会释放它们。

代码语言:javascript
复制
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')
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8855974

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档