112

假设我有一个名为choice它的变量等于 2。我将如何访问该变量的名称?相当于

In [53]: namestr(choice)
Out[53]: 'choice'

用于制作字典。有一个很好的方法可以做到这一点,我只是想念它。

编辑:

这样做的原因是这样的。我正在运行一些数据分析的东西,我用多个参数调用程序,我想在运行时调整或不调整。我从格式为的 .config 文件中读取了上次运行中使用的参数

filename
no_sig_resonance.dat

mass_peak
700

choice
1,2,3

当提示输入值时,会显示先前使用的值,并且空字符串输入将使用先前使用的值。

我的问题出现是因为在编写这些值已被扫描到的字典时。如果需要一个参数,我运行get_param它访问文件并找到参数。

我想我会通过阅读 . config归档一次并从中生成字典。我最初避免这样做是出于……我不再记得的原因。完美的情况来更新我的代码!

4

8 回答 8

131

如果你坚持,这里有一些可怕的基于检查的解决方案。

import inspect, re

def varname(p):
  for line in inspect.getframeinfo(inspect.currentframe().f_back)[3]:
    m = re.search(r'\bvarname\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)\s*\)', line)
    if m:
      return m.group(1)

if __name__ == '__main__':
  spam = 42
  print varname(spam)

我希望它会激发您重新评估您遇到的问题并寻找另一种方法。

于 2009-02-26T23:05:16.963 回答
88

要回答您的原始问题:

def namestr(obj, namespace):
    return [name for name in namespace if namespace[name] is obj]

例子:

>>> a = 'some var'
>>> namestr(a, globals())
['a']

正如@rbright 已经指出的那样,无论您做什么,都可能有更好的方法来做到这一点。

于 2009-02-26T23:14:46.130 回答
16

如果你试图这样做,这意味着你做错了什么。考虑使用 adict代替。

def show_val(vals, name):
    print "Name:", name, "val:", vals[name]

vals = {'a': 1, 'b': 2}
show_val(vals, 'b')

输出:

Name: b val: 2
于 2009-02-26T22:52:50.550 回答
10

你不能,因为 Python 中没有变量,只有名称。

例如:

> a = [1,2,3]
> b = a
> a is b
True

这两个中的哪一个现在是正确的变量?a和之间没有区别b

以前也有类似的问题

于 2009-02-26T22:31:25.780 回答
8

我建议您描述您面临的问题,而不是询问具体解决方案的详细信息;我想你会得到更好的答案。我这么说是因为几乎可以肯定有更好的方法来做你想做的任何事情。通常不需要以这种方式访问​​变量名来解决任何语言的问题。

也就是说,您所有的变量名称都已经在字典中,可以通过内置函数localsglobals访问这些字典。为您正在检查的范围使用正确的范围。

检查这些字典的少数常见习语之一是简单的字符串插值:

>>> first = 'John'
>>> last = 'Doe'
>>> print '%(first)s %(last)s' % globals()
John Doe

这类东西往往比替代方案更具可读性,即使它需要按名称检查变量。

于 2009-02-26T22:49:37.173 回答
4

通过急切的评估,变量在您查看它们时基本上都会变成它们的值(解释一下)。也就是说,Python 确实有内置的命名空间。例如,locals() 将返回一个字典,将函数的变量名称映射到它们的值,而 globals() 对模块执行相同的操作。因此:

for name, value in globals().items():
    if value is unknown_variable:
        ... do something with name

请注意,您无需导入任何内容即可访问 locals() 和 globals()。

此外,如果一个值有多个别名,则遍历命名空间只会找到第一个。

于 2009-02-26T22:45:40.037 回答
2

像这样的东西对你有用吗?

>>> def namestr(**kwargs):
...     for k,v in kwargs.items():
...       print "%s = %s" % (k, repr(v))
...
>>> namestr(a=1, b=2)
a = 1
b = 2

在你的例子中:

>>> choice = {'key': 24; 'data': None}
>>> namestr(choice=choice)
choice = {'data': None, 'key': 24}
>>> printvars(**globals())
__builtins__ = <module '__builtin__' (built-in)>
__name__ = '__main__'
__doc__ = None
namestr = <function namestr at 0xb7d8ec34>
choice = {'data': None, 'key': 24}
于 2009-02-26T23:01:26.490 回答
2

对于如何读取配置参数的修订问题,我强烈建议您节省一些时间和精力并使用ConfigParser或(我的首选工具)ConfigObj

它们可以做你需要的一切,它们易于使用,而且已经有人担心如何让它们正常工作了!

于 2009-02-26T23:39:04.917 回答