将variables名称转换为string?

我想将一个pythonvariables名称转换为相应的string,如图所示。 任何想法如何?

var = {} print ??? # Would like to see 'var' something_else = 3 print ??? # Would print 'something_else' 

有一个使用场景,你可能需要这个。 我并不是暗示没有更好的方法或实现相同的function。

如果出现错误,在debugging模式和其他类似的情况下,这将是有用的,以便“转储”任意的字典列表。

需要什么,是eval()函数的反转:

 get_indentifier_name_missing_function() 

这会将标识符名称(“variables”,“字典”等)作为参数,并返回一个包含标识符名称的string。


考虑下面的现状:

 random_function(argument_data) 

如果将一个标识符名称('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>) 

从我的理解,只有内存地址被传递给函数:

 <function at 0xafff78>(<object at 0xb1ce10>) 

因此,需要将一个string作为parameter passing给random_function() ,以便该函数具有参数的标识符名称:

 random_function('argument_data') 

在random_function()里面

 def random_function(first_argument): 

,可以使用已经提供的string'argument_data'来:

  1. 作为“标识符名称”(显示,logging,string拆分/连续,无论)
  2. 反馈eval()函数以获得对实际标识符的引用,从而引用实际数据:

     print("Currently working on", first_argument) some_internal_var = eval(first_argument) print("here comes the data: " + str(some_internal_var)) 

不幸的是,这在所有情况下都不起作用。 它只有在random_function()可以将'argument_data'stringparsing为一个实际的标识符时才有效。 也就是说,如果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)) ###### 

预期的结果是:

 Currently working on: argument_data here comes the data: my data 

由于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 

现在,考虑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) ) ###### 

预期的结果是:

 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. 

不幸的是, get_indentifier_name_missing_function()不会看到“原始”标识符名称( some_dictionary_some_other_dictionary_2some_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. 

所以,在这种情况下, 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) ) ###### 

结论是:

  • Python只将内存地址作为parameter passing给函数。
  • 如果名称标识符在当前名称空间中可用,则表示标识符名称的string只能由eval()函数引用回实际标识符。
  • eval()函数的假设反转,在调用代码不直接标识名称的情况下是没有用的。 例如在任何调用函数内。
  • 目前需要传递一个函数:
    1. 代表标识符名称的string
    2. 实际的标识符(内存地址)

这可以通过将'string'eval('string')传递给被调用的函数来实现。 我认为这是在任意函数,模块,命名空间中解决这个egg-chicken问题的最“通用”方式,而不使用corner-case解决scheme。 唯一的缺点是使用eval()函数很容易导致不安全的代码。 必须注意不要将eval()函数与几乎任何东西,特别是未经过滤的外部input数据一起input。

从技术上讲,这些信息可以提供给你,但是正如其他人所问,你将如何合理地使用它?

 >>> x = 52 >>> globals() {'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 'x': 52, '__doc__': None, '__package__': None} 

这表明variables名在globals()字典中以stringforms出现。

 >>> globals().keys()[2] 'x' 

在这种情况下,它恰好是第三个关键,但没有可靠的方法来知道给定的variables名称将在哪里结束

 >>> for k in globals().keys(): ... if not k.startswith("_"): ... print k ... x >>> 

你可以像这样过滤出系统variables,但是你仍然可以获得所有的物品。 只是运行上面的代码创build了另一个variables“k”,在字典中改变了“x”的位置。

但也许这对你是一个有用的开始。 如果你告诉我们你想要这个function,可能会给出更多有用的信息。

这不可能。

在Python中,确实没有任何“variables”这样的东西。 Python真正具有的是可以绑定对象的“名称”。 这个对象的名字,如果有的话,它可能会被绑定。 它可能会被绑定到几十个不同的名字,或者没有。

考虑这个例子:

 foo = 1 bar = 1 baz = 1 

现在,假设你有一个值为1的整数对象,并且你想向后工作并find它的名字。 你打印什么? 三个不同的名字有这个对象绑定到他们,都是同样有效的。

在Python中,名称是访问对象的一种方式,因此无法直接使用名称。 可能有一些聪明的方法来破解Python的字节码或者某个东西来获得名字的价值,但这最多是一个会客的伎俩。

如果你知道你想要print foo来打印"foo" ,那么你可能只需要首先执行print "foo"

编辑:我已经稍微改变了措辞,使这更清楚。 而且,这是一个更好的例子:

 foo = 1 bar = foo baz = foo 

在实践中,Python重复使用同一个对象来处理常见值(如0或1),因此第一个示例应该将同一个对象绑定到所有三个名称。 但是这个例子很清楚:同样的东西被绑定到foo,bar和baz。

我search了这个问题,因为我想要一个Python程序来打印程序中某些variables的赋值语句。 例如,它可能会打印“foo = 3,bar = 21,baz = 432”。 打印function将需要stringforms的variables名称。 我可以用string“foo”,“bar”和“baz”来提供我的代码,但是这就像是在重复我自己。 阅读之前的答案后,我开发了下面的解决scheme。

globals()函数的行为类似于带有variables名(stringforms)的字典。 我想从globals()中检索对应于每个variables值的键。 globals()。items()方法返回一个元组列表; 在每个元组中,第一项是variables名(作为string),第二项是variables值。 我的variables名()函数search该列表来查找variables名称(s)对应的variables的名称我需要以stringforms的值。

函数itertools.ifilter()通过testingglobals()。items()列表中的函数lambda x: var is globals()[x[0]]中的每个元组进行search。 在那个函数中,x是被testing的元组; x [0]是variables名(作为string),x [1]是值。 lambda函数testing被测variables的值是否与传递给variablename()的variables的值相同。 事实上,通过使用is运算符,lambda函数testing被测variables的名称是否与传递给variablename()的variables绑定到完全相同的对象。 如果是这样,元组通过testing并由ifilter()返回。

itertools.ifilter()函数实际上会返回一个迭代器,它只有在正确调用之后才会返回任何结果。 为了使它正确调用,我把它放在列表理解[tpl[0] for tpl ... globals().items())] 。 列表parsing仅保存variables名称tpl[0] ,忽略variables值。 创build的列表包含一个或多个名称(作为string),这些名称绑定到传递给variablename()的variables的值。

在下面显示的variablename()的用法中,所需的string作为列表中的元素返回。 在很多情况下,这将是唯一的项目。 如果另一个variables名称分配了相同的值,那么列表将会变长。

 >>> 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'] 

你不知何故不得不引用你想要打印的名字的variables。 所以它看起来像:

 print varname(something_else) 

没有这样的function,但是如果有的话就没有意义了。 你必须inputsomething_else ,所以你只要在左边和右边input引号就可以把string打印出来:

 print "something_else" 

你想达到什么目的? 绝对没有理由永远不要做你所描述的事情,并且可能有更好的解决scheme来解决你正在试图解决的问题。

你要求的最明显的select是字典。 例如:

 >>> my_data = {'var': 'something'} >>> my_data['something_else'] = 'something' >>> print my_data.keys() ['var', 'something_else'] >>> print my_data['var'] something 

主要是作为挑战,我实现了你想要的输出。 请不要使用此代码!

 #!/usr/bin/env python2.6 class NewLocals: """Please don't ever use this code..""" def __init__(self, initial_locals): self.prev_locals = list(initial_locals.keys()) def show_new(self, new_locals): output = ", ".join(list(set(new_locals) - set(self.prev_locals))) self.prev_locals = list(new_locals.keys()) return output # Set up eww = None eww = NewLocals(locals()) # "Working" requested code var = {} print eww.show_new(locals()) # Outputs: var something_else = 3 print eww.show_new(locals()) # Outputs: something_else # Further testing another_variable = 4 and_a_final_one = 5 print eww.show_new(locals()) # Outputs: another_variable, and_a_final_one 

只要它是一个variables,而不是第二类,这里适用于我:

 def print_var_name(variable): for name in globals(): if eval(name) == variable: print name foo = 123 print_var_name(foo) >>>foo 

这发生在class级成员身上:

 class xyz: def __init__(self): pass member = xyz() print_var_name(member) >>>member 

回答这个类(例如):

 abc = xyz print_var_name(abc) >>>abc >>>xyz 

所以对于类,它给你的名字和特性

Django在生成字段名称时不这样做吗?

http://docs.djangoproject.com/en/dev//topics/db/models/#verbose-field-names

对我来说似乎是合理的。

我认为这是一个很酷的解决scheme,我想你可以得到最好的。 但是,你认为有什么办法来处理这个令人费解的结果,你的function可能会返回吗? 由于“is”操作符的意外行为与整数显示,低整数和相同值的string获得由pythoncaching,以便您的可变名称函数可能priovigh结果很可能。 在我的情况下,我想创build一个装饰器,通过varialbename向我的类添加一个新的variables,我通过它:

 def inject(klass, dependency): klass.__dict__["__"+variablename(dependency)]=dependency 

但是,如果你的方法返回的结果模糊,我怎么知道我添加的variables的名称?

 var any_var="myvarcontent" var myvar="myvarcontent" @inject(myvar) class myclasss(): def myclass_method(self): print self.__myvar #I can not be sure, that this variable will be set... 

也许如果我也将检查本地列表,我可以至less从列表中删除“依赖” – variables,但这不会是一个可靠的结果。

这是一个简洁的变体,可以让你指定任何目录。 使用目录查找任何内容的问题是多个variables可以具有相同的值。 所以这个代码返回一个可能的variables列表。

 def varname( var, dir=locals()): return [ key for key, val in dir.items() if id( val) == id( var)] 
 print "var" print "something_else" 

还是你的意思是something_else?

这将适用于简单的数据types(str,int,float,list等)

 >>> def my_print(var_str): 
       print var_str +':',globals()[var_str]
 >>> a = 5
 >>> b = ['hello',',world!']
 >>> my_print('a')
 a:5
 >>> my_print('b')
 b:['hello',',world!']