我希望能够以字符串的形式获取变量的名称,但我不知道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(),所以我猜有一种方法。
大多数对象没有__name__属性。(类、函数和模块可以;还有其他内置类型吗?)
除了print("my_var"),你还期望print(my_var.__name__)有什么?你能直接使用字符串吗?
你可以"slice" a dict:
def dict_slice(D, keys, default=None):
return dict((k, D.get(k, default)) for k in keys)
print dict_slice(locals(), ["foo", "bar"])
# or use set literal syntax if you have a recent enough version:
print dict_slice(locals(), {"foo", "bar"})
另外:
throw = object() # sentinel
def dict_slice(D, keys, default=throw):
def get(k):
v = D.get(k, throw)
if v is not throw:
return v
if default is throw:
raise KeyError(k)
return default
return dict((k, get(k)) for k in keys)
这是一个黑客。它不能在所有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')])
我发现如果你已经有了一个特定的值列表,那么@S描述的方式。抽签是最好的;然而,下面描述的方法可以很好地在整个代码中添加所有的变量和类,而不需要提供变量名,尽管如果你想要指定它们。可以扩展代码以排除类。
import types
import math # mainly showing that you could import what you will before d
# Everything after this counts
d = dict(globals())
def kv_test(k,v):
return (k not in d and
k not in ['d','args'] and
type(v) is not types.FunctionType)
def magic_print(*args):
if len(args) == 0:
return {k:v for k,v in globals().iteritems() if kv_test(k,v)}
else:
return {k:v for k,v in magic_print().iteritems() if k in args}
if __name__ == '__main__':
foo = 1
bar = 2
baz = 3
print magic_print()
print magic_print('foo')
print magic_print('foo','bar')
输出:
{'baz': 3, 'foo': 1, 'bar': 2}
{'foo': 1}
{'foo': 1, 'bar': 2}