Bra*_*rey 57 python string variables
我想将python变量名转换为等效的字符串,如图所示.有什么想法?
var = {}
print ??? # Would like to see 'var'
something_else = 3
print ??? # Would print 'something_else'
Run Code Online (Sandbox Code Playgroud)
Pet*_*ria 39
有一种使用场景,您可能需要这样做.我并不是说没有更好的方法或实现相同的功能.
这对于在出错,在调试模式和其他类似情况下"转储"任意字典列表非常有用.
需要的是eval()功能的反面:
get_indentifier_name_missing_function()
Run Code Online (Sandbox Code Playgroud)
它将标识符名称('variable','dictionary'等)作为参数,并返回包含标识符名称的字符串.
考虑以下当前的事态:
random_function(argument_data)
Run Code Online (Sandbox Code Playgroud)
如果将标识符名称('function','variable','dictionary'等)argument_data传递给random_function()(另一个标识符名称),则实际上将标识符(例如:)传递<argument_data object at 0xb1ce10>给另一个标识符(例如:) <function random_function at 0xafff78>:
<function random_function at 0xafff78>(<argument_data object at 0xb1ce10>)
Run Code Online (Sandbox Code Playgroud)
根据我的理解,只有内存地址传递给函数:
<function at 0xafff78>(<object at 0xb1ce10>)
Run Code Online (Sandbox Code Playgroud)
因此,需要传递一个字符串作为参数random_function(),以使该函数具有参数的标识符名称:
random_function('argument_data')
Run Code Online (Sandbox Code Playgroud)
在random_function()里面
def random_function(first_argument):
Run Code Online (Sandbox Code Playgroud)
,人们会使用已经提供的字符串'argument_data':
提供eval()函数以获得对实际标识符的引用,因此,引用实际数据:
print("Currently working on", first_argument)
some_internal_var = eval(first_argument)
print("here comes the data: " + str(some_internal_var))
Run Code Online (Sandbox Code Playgroud)不幸的是,这并不适用于所有情况.它只有在random_function()可以将'argument_data'字符串解析为实际标识符时才有效.即如果argument_data标识符名称在random_function()命名空间中可用.
情况并非总是这样:
# main1.py
import some_module1
argument_data = 'my data'
some_module1.random_function('argument_data')
# some_module1.py
def random_function(first_argument):
print("Currently working on", first_argument)
some_internal_var = eval(first_argument)
print("here comes the data: " + str(some_internal_var))
######
Run Code Online (Sandbox Code Playgroud)
预期结果将是:
Currently working on: argument_data
here comes the data: my data
Run Code Online (Sandbox Code Playgroud)
因为argument_data标识符名称在random_function()命名空间中不可用,所以这将产生:
Currently working on argument_data
Traceback (most recent call last):
File "~/main1.py", line 6, in <module>
some_module1.random_function('argument_data')
File "~/some_module1.py", line 4, in random_function
some_internal_var = eval(first_argument)
File "<string>", line 1, in <module>
NameError: name 'argument_data' is not defined
Run Code Online (Sandbox Code Playgroud)
现在,考虑一下如上所述get_indentifier_name_missing_function()行为的假设用法.
这是一个虚拟的Python 3.0代码:.
# main2.py
import some_module2
some_dictionary_1 = { 'definition_1':'text_1',
'definition_2':'text_2',
'etc':'etc.' }
some_other_dictionary_2 = { 'key_3':'value_3',
'key_4':'value_4',
'etc':'etc.' }
#
# more such stuff
#
some_other_dictionary_n = { 'random_n':'random_n',
'etc':'etc.' }
for each_one_of_my_dictionaries in ( some_dictionary_1,
some_other_dictionary_2,
...,
some_other_dictionary_n ):
some_module2.some_function(each_one_of_my_dictionaries)
# some_module2.py
def some_function(a_dictionary_object):
for _key, _value in a_dictionary_object.items():
print( get_indentifier_name_missing_function(a_dictionary_object) +
" " +
str(_key) +
" = " +
str(_value) )
######
Run Code Online (Sandbox Code Playgroud)
预期结果将是:
some_dictionary_1 definition_1 = text_1
some_dictionary_1 definition_2 = text_2
some_dictionary_1 etc = etc.
some_other_dictionary_2 key_3 = value_3
some_other_dictionary_2 key_4 = value_4
some_other_dictionary_2 etc = etc.
......
......
......
some_other_dictionary_n random_n = random_n
some_other_dictionary_n etc = etc.
Run Code Online (Sandbox Code Playgroud)
不幸的是,get_indentifier_name_missing_function()不会看到"原始的"标识符名称(some_dictionary_,some_other_dictionary_2,some_other_dictionary_n).它只会看到a_dictionary_object标识符名称.
因此,真正的结果将是:
a_dictionary_object definition_1 = text_1
a_dictionary_object definition_2 = text_2
a_dictionary_object etc = etc.
a_dictionary_object key_3 = value_3
a_dictionary_object key_4 = value_4
a_dictionary_object etc = etc.
......
......
......
a_dictionary_object random_n = random_n
a_dictionary_object etc = etc.
Run Code Online (Sandbox Code Playgroud)
因此,eval()在这种情况下,函数的反向将不那么有用.
目前,人们需要这样做:
# main2.py same as above, except:
for each_one_of_my_dictionaries_names in ( 'some_dictionary_1',
'some_other_dictionary_2',
'...',
'some_other_dictionary_n' ):
some_module2.some_function( { each_one_of_my_dictionaries_names :
eval(each_one_of_my_dictionaries_names) } )
# some_module2.py
def some_function(a_dictionary_name_object_container):
for _dictionary_name, _dictionary_object in a_dictionary_name_object_container.items():
for _key, _value in _dictionary_object.items():
print( str(_dictionary_name) +
" " +
str(_key) +
" = " +
str(_value) )
######
Run Code Online (Sandbox Code Playgroud)
eval()如果名称标识符在当前名称空间中可用,则表示标识符名称的字符串只能由函数引用回实际标识符.eval()标识符名称没有被调用代码直接"看到" ,则函数的假设反转将不会有用.例如在任何被调用的函数内这可以通过同时传递'string'和eval('string')调用函数来实现.我认为这是在任意函数,模块,名称空间中解决这个鸡蛋问题的最"通用"方法,而不使用角落案例解决方案.唯一的缺点是使用该eval()功能可能很容易导致不安全的代码.必须注意不要eval()用几乎任何东西来提供功能,特别是未经过滤的外部输入数据.
Ali*_*ice 11
只要它是一个变量而不是第二个类,这对我有用:
def print_var_name(variable):
for name in globals():
if eval(name) == variable:
print name
foo = 123
print_var_name(foo)
>>>foo
Run Code Online (Sandbox Code Playgroud)
这发生在班级成员身上:
class xyz:
def __init__(self):
pass
member = xyz()
print_var_name(member)
>>>member
Run Code Online (Sandbox Code Playgroud)
这对于类(例如):
abc = xyz
print_var_name(abc)
>>>abc
>>>xyz
Run Code Online (Sandbox Code Playgroud)
因此,对于类,它为您提供名称和属性
小智 10
我搜索了这个问题,因为我想要一个Python程序来打印程序中某些变量的赋值语句.例如,它可能会打印"foo = 3,bar = 21,baz = 432".print函数需要字符串形式的变量名.我可以用字符串"foo","bar"和"baz"提供我的代码,但这感觉就像在重复自己.在阅读了之前的答案后,我开发了以下解决方案.
globals()函数的行为类似于带有变量名称(以字符串形式)作为键的dict.我想从globals()中检索与每个变量的值对应的键.方法globals().items()返回元组列表; 在每个元组中,第一项是变量名(作为字符串),第二项是变量值.我的variablename()函数搜索该列表,以查找与字符串形式所需名称的变量值对应的变量名称.
函数itertools.ifilter()通过使用函数测试globals().items()列表中的每个元组来进行搜索lambda x: var is globals()[x[0]].在那个函数中x是被测试的元组; x [0]是变量名(作为字符串),x [1]是值.lambda函数测试测试变量的值是否与传递给variablename()的变量的值相同.实际上,通过使用is运算符,lambda函数测试测试变量的名称是否与传递给variablename()的变量绑定到完全相同的对象.如果是,则元组通过测试并由ifilter()返回.
itertools.ifilter()函数实际上返回一个迭代器,它在正确调用之前不会返回任何结果.为了正确调用它,我把它放在列表理解中[tpl[0] for tpl ... globals().items())].列表推导仅保存变量名称tpl[0],忽略变量值.创建的列表包含一个或多个名称(作为字符串),这些名称绑定到传递给variablename()的变量的值.
在下面显示的variablename()的使用中,所需的字符串作为列表中的元素返回.在许多情况下,它将是列表中唯一的项目.但是,如果为另一个变量名指定了相同的值,则列表将更长.
>>> def variablename(var):
... import itertools
... return [tpl[0] for tpl in
... itertools.ifilter(lambda x: var is x[1], globals().items())]
...
>>> var = {}
>>> variablename(var)
['var']
>>> something_else = 3
>>> variablename(something_else)
['something_else']
>>> yet_another = 3
>>> variablename(something_else)
['yet_another', 'something_else']
Run Code Online (Sandbox Code Playgroud)
这是不可能的.
在Python中,确实没有任何"变量"这样的东西.Python真正拥有的是"名称",它们可以绑定对象.它对象可能会绑定哪些名称(如果有的话)没有区别.它可能会绑定几十个不同的名称,或者没有.
考虑这个例子:
foo = 1
bar = 1
baz = 1
Run Code Online (Sandbox Code Playgroud)
现在,假设您有一个值为1的整数对象,并且您想要向后工作并找到它的名称.你会打印什么?三个不同的名称将该对象绑定到它们,并且所有这些都同样有效.
在Python中,名称是访问对象的一种方式,因此无法直接使用名称.可能有一些聪明的方法来破解Python字节码或某些东西来获取名称的值,但这最多只是一个客厅技巧.
如果您知道要print foo打印"foo",那么您最好print "foo"先执行.
编辑:我稍微改变了措辞,使其更加清晰.此外,这是一个更好的例子:
foo = 1
bar = foo
baz = foo
Run Code Online (Sandbox Code Playgroud)
在实践中,Python为具有常见值(如0或1)的整数重用相同的对象,因此第一个示例应将同一对象绑定到所有三个名称.但是这个例子很清楚:同一个对象被绑定到foo,bar和baz.
从技术上讲,这些信息可供您使用,但正如其他人所问,您将如何以合理的方式使用它?
>>> x = 52
>>> globals()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__',
'x': 52, '__doc__': None, '__package__': None}
Run Code Online (Sandbox Code Playgroud)
这表明变量名在globals()字典中以字符串形式出现.
>>> globals().keys()[2]
'x'
Run Code Online (Sandbox Code Playgroud)
在这种情况下,它碰巧是第三个键,但没有可靠的方法来知道给定变量名称的最终位置
>>> for k in globals().keys():
... if not k.startswith("_"):
... print k
...
x
>>>
Run Code Online (Sandbox Code Playgroud)
您可以过滤掉这样的系统变量,但您仍然可以获得所有自己的项目.刚刚运行上面的代码创建了另一个变量"k",它改变了dict中"x"的位置.
但也许这对你来说是一个有用的开始.如果您告诉我们您希望使用此功能,可能会提供更多有用的信息.
完全可以使用 python-varname 包(python3):
from varname import nameof
s = 'Hey!'
print (nameof(s))
Run Code Online (Sandbox Code Playgroud)
输出:
s
Run Code Online (Sandbox Code Playgroud)
在这里获取包裹:
https://github.com/pwwang/python-varname