将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'
来:
- 作为“标识符名称”(显示,logging,string拆分/连续,无论)
-
反馈
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_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.
所以,在这种情况下, 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()
函数的假设反转,在调用代码不直接标识名称的情况下是没有用的。 例如在任何调用函数内。 - 目前需要传递一个函数:
- 代表标识符名称的string
- 实际的标识符(内存地址)
这可以通过将'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!']