如何在 python 中打印变量名称?[重复]
- 2024-12-17 08:30:00
- admin 原创
- 139
问题描述:
假设我有一个名为choice
it is equal to 2 的变量。我该如何访问该变量的名称?相当于
In [53]: namestr(choice)
Out[53]: 'choice'
用于制作字典。有一个很好的方法可以做到这一点,但我却错过了。
编辑:
这样做的原因如下。我正在运行一些数据分析程序,我使用多个参数调用程序,这些参数我想在运行时进行调整或不进行调整。我从格式为 .config 的文件中读取了上次运行中使用的参数
filename
no_sig_resonance.dat
mass_peak
700
choice
1,2,3
当提示输入值时,将显示先前使用的值,而空字符串输入将使用先前使用的值。
我的问题是因为在编写这些值被扫描到的字典时。如果需要一个参数,我会运行get_param
访问文件并找到该参数。
我认为通过读取 . 文件一次并从中生成字典,我将完全避免这个问题config
。我最初避免这样做是因为......原因我已记不清了。这是更新我的代码的绝佳情况!
解决方案 1:
如果您坚持的话,这里有一些基于检查的可怕的解决方案。
import inspect, re
def varname(p):
for line in inspect.getframeinfo(inspect.currentframe().f_back)[3]:
m = re.search(r'varnames*(s*([A-Za-z_][A-Za-z0-9_]*)s*)', line)
if m:
return m.group(1)
if __name__ == '__main__':
spam = 42
print varname(spam)
我希望它能够激励您重新评估您遇到的问题并寻找另一种方法。
解决方案 2:
回答你最初的问题:
def namestr(obj, namespace):
return [name for name in namespace if namespace[name] is obj]
例子:
>>> a = 'some var'
>>> namestr(a, globals())
['a']
我们可以使用inspect
模块获取调用者的命名空间:
import inspect
def names_in_caller(obj, depth=2) -> list[str]:
"""Return *obj*'s names in the caller namespace.
Default *depth* is 2 meaning that caller's caller names
are returned
"""
f = inspect.currentframe()
for _ in range(depth):
f = f.f_back
return namestr(obj, f.f_locals)
例子:
>>> def f(n):
... n_name = name_in_caller(n) # find name in the caller
... return f"{n_name}={n}" # like f"{n=}" but with callers' name
...
>>> a = 1
>>> f(a)
"['a']=1"
>>> b = 1
>>> f(a)
"['a', 'b']=1"
正如@rbright 已经指出的那样,无论您做什么,都可能有更好的方法来做。
解决方案 3:
如果您尝试这样做,则说明您做错了。请考虑改用dict
。
def show_val(vals, name):
print "Name:", name, "val:", vals[name]
vals = {'a': 1, 'b': 2}
show_val(vals, 'b')
输出:
Name: b val: 2
解决方案 4:
我建议你描述一下你面临的问题,而不是询问具体解决方案的细节;我认为你会得到更好的答案。我这样说是因为几乎肯定有更好的方法来完成你想做的事情。在任何语言中,以这种方式访问变量名通常都不是解决问题的必要条件。
也就是说,所有变量名都已存在于字典中,可通过内置函数locals和globals访问。根据检查的范围使用正确的一个。
检查这些字典的几个常见习惯用法之一是为了简单的字符串插值:
>>> first = 'John'
>>> last = 'Doe'
>>> print '%(first)s %(last)s' % globals()
John Doe
尽管它需要通过名称检查变量,但这种方法比其他方法更易于阅读。
解决方案 5:
你不能,因为 Python 中没有变量,只有名称。
例如:
> a = [1,2,3]
> b = a
> a is b
True
a
这两个中哪一个是正确的变量?和之间没有区别b
。
之前也有过类似的问题。
解决方案 6:
这样的事情对你有用吗?
>>> 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}
解决方案 7:
通过急切求值,变量基本上会在您查看它们时随时变成它们的值(解释一下)。也就是说,Python 确实有内置命名空间。例如,locals() 将返回一个将函数变量的名称映射到其值的字典,globals() 对模块执行相同操作。因此:
for name, value in globals().items():
if value is unknown_variable:
... do something with name
请注意,您不需要导入任何内容就可以访问 locals() 和 globals()。
此外,如果一个值有多个别名,则遍历命名空间只会找到第一个。
解决方案 8:
对于如何读取配置参数的修改问题,我强烈建议您节省一些时间和精力并使用ConfigParser或(我首选的工具)ConfigObj。
它们可以满足您的所有需求,并且易于使用,而且其他人已经担心如何让它们正常工作了!