我希望能够以字符串的形式获取变量的名称,但我不知道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(),所以我猜有一种方法。


当前回答

我认为我的问题将有助于说明为什么这个问题是有用的,它可能会让你更深入地了解如何回答这个问题。我写了一个小函数来对代码中的各种变量进行快速内联头部检查。基本上,它列出了变量名、数据类型、大小和其他属性,因此我可以快速捕捉到我所犯的任何错误。代码很简单:

def details(val):
  vn = val.__name__                 #  If such a thing existed
  vs = str(val)
  print("The Value of "+ str(vn) + " is " + vs)
  print("The data type of " + vn + " is " + str(type(val)))

所以如果你有一些复杂的字典/列表/元组的情况,让解释器返回你分配的变量名会很有帮助。例如,这里有一个奇怪的字典:

m = 'abracadabra'
mm=[]    
for n in m:
  mm.append(n)
mydic = {'first':(0,1,2,3,4,5,6),'second':mm,'third':np.arange(0.,10)}



details(mydic)

The Value of mydic is {'second': ['a', 'b', 'r', 'a', 'c', 'a', 'd', 'a', 'b', 'r', 'a'], 'third': array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.]), 'first': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
The data type of mydic is <type 'dict'>

details(mydic['first'])
The Value of mydic['first'] is (0, 1, 2, 3, 4, 5, 6)]
The data type of mydic['first'] is <type 'list'>

details(mydic.keys())
The Value of mydic.keys() is ['second', 'third', 'first']
The data type of mydic.keys() is <type 'tuple'>

details(mydic['second'][0])
The Value of mydic['second'][0] is a
The data type of mydic['second'][0] is <type 'str'>

我不确定我是否把它放在正确的地方,但我想它可能有帮助。我希望如此。

其他回答

这是一个黑客。它不能在所有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')])

我写了包巫术健壮地做这种魔法。你可以这样写:

from sorcery import dict_of

my_dict = dict_of(foo, bar)
import re
import traceback

pattren = re.compile(r'[\W+\w+]*get_variable_name\((\w+)\)')
def get_variable_name(x):
    return pattren.match( traceback.extract_stack(limit=2)[0][3]) .group(1)

a = 1
b = a
c = b
print get_variable_name(a)
print get_variable_name(b)
print get_variable_name(c)

正如unwind所说,这不是你在Python中真正做的事情——变量实际上是对象的名称映射。

然而,这里有一种方法可以尝试去做:

 >>> a = 1
 >>> for k, v in list(locals().iteritems()):
         if v is a:
             a_as_str = k
 >>> a_as_str
 a
 >>> type(a_as_str)
 'str'

在python 2.7及更新版本中,还有字典理解,这使得它更短一些。如果可能的话,我会使用getattr代替eval (eval是邪恶的),就像在顶部的答案。Self可以是任何有你正在看的上下文的对象。它可以是一个对象或locals=locals()等。

{name: getattr(self, name) for name in ['some', 'vars', 'here]}