我希望能够以字符串的形式获取变量的名称,但我不知道Python是否有那么多的自省功能。喜欢的东西:

>>> print(my_var.__name__)
'my_var'

我想这样做是因为我有一堆变量,我想把它们转换成一个字典,比如:

bar = True
foo = False
>>> my_dict = dict(bar=bar, foo=foo)
>>> print my_dict 
{'foo': False, 'bar': True}

但我想要更自动的。

Python有locals()和vars(),所以我猜有一种方法。


当前回答

我一直很想这么做。这个技巧与rlotun的建议非常相似,但它是一行代码,对我来说很重要:

blah = 1
blah_name = [ k for k,v in locals().iteritems() if v is blah][0]

Python 3 +

blah = 1
blah_name = [ k for k,v in locals().items() if v is blah][0]

其他回答

这是一个黑客。它不能在所有Python实现发行版上工作(特别是那些没有traceback.extract_stack的发行版)。

import traceback

def make_dict(*expr):
    (filename,line_number,function_name,text)=traceback.extract_stack()[-2]
    begin=text.find('make_dict(')+len('make_dict(')
    end=text.find(')',begin)
    text=[name.strip() for name in text[begin:end].split(',')]
    return dict(zip(text,expr))

bar=True
foo=False
print(make_dict(bar,foo))
# {'foo': False, 'bar': True}

注意,这个黑客是脆弱的:

make_dict(bar,
          foo)

(在2行上调用make_dict)将无法工作。

与其尝试用foo和bar值生成dict, 从字符串变量名'foo'和'bar'中生成dict会更加python化:

dict([(name,locals()[name]) for name in ('foo','bar')])

Python3。使用inspect来捕获调用的本地名称空间,然后使用这里提供的想法。可以返回一个以上的答案,正如已经指出的。

def varname(var):
  import inspect
  frame = inspect.currentframe()
  var_id = id(var)
  for name in frame.f_back.f_locals.keys():
    try:
      if id(eval(name)) == var_id:
        return(name)
    except:
      pass

你真的想这么做吗?

dict( (name,eval(name)) for name in ['some','list','of','vars'] )

例子

>>> some= 1
>>> list= 2
>>> of= 3
>>> vars= 4
>>> dict( (name,eval(name)) for name in ['some','list','of','vars'] )
{'list': 2, 'some': 1, 'vars': 4, 'of': 3}

在python3中,该函数将获取堆栈中最外层的名称:

import inspect


def retrieve_name(var):
        """
        Gets the name of var. Does it from the out most frame inner-wards.
        :param var: variable to get name from.
        :return: string
        """
        for fi in reversed(inspect.stack()):
            names = [var_name for var_name, var_val in fi.frame.f_locals.items() if var_val is var]
            if len(names) > 0:
                return names[0]

它在代码的任何地方都有用。遍历反向堆栈,寻找第一个匹配项。

在python3中,这很容易

myVariable = 5
for v in locals():
  if id(v) == id("myVariable"):
    print(v, locals()[v])

这将打印:

myVariable 5