Re: Can I get a value's name
jalanb3 wrote: Context for this question arises from some recent code. In particular the replace_line method, which takes in a regexp to look for, and a replacement for when it matches. It is supposed to work for single lines only (we add ^ and $ to the regexp), so arguments which have '\n' in them are not accepted. So at start of the method we search for such bad chars, and the code ends up something like this: def replace_line(pattern,replacement): errors = '\n' in pattern and [ 'pattern' ] or [] errors += '\n' in replacement and [ 'replacement' ] or [] values = [ locals()[e] for e in errors ] # etc, etc, and eventually: print 'Argument %s is bad : %s' % (errors[0],values[0]) And the question arises from that locals() line: Given a variable name I can use locals() to get the value Is there a way to do it the other way round Given the value, can I get the variable name ? For example, suppose I had started like this (using the variables, not strings with their names) def replace_line(pattern,replacement): values = '\n' in pattern and [ pattern ] or [] values += '\n' in replacement and [ replacement ] or [] Can I later get the name pattern via values[0]? If this was an array in another language: Of course not, values[0] is a copy of the value so the connection to the variable is lost But, AFAIK, in Python values[0] is just a rename of pattern so there might be a way to get through to the original variable No, values[0] gives a reference to the value stored at index 0 of the values array, which does not contain the name. In particular, the name and all other information about the expression itself is lost. A value generally does not contain the pattern or any kind of name information (although class, method, and function instances contain some symbolic information in them). Study the concept of 'references' and all of this will become more clear. The only way to do something like what you want would be to search globals() or locals() for the value (depending on the context), but that would be an extremely ugly hack. Chances are that if you want to do this, you need to rethink the problem instead. # horribly bad, but sort of working, code follows: foo = 'find me!' def find_var(x): '''returns the name associated with a value''' for k,v in globals().items(): if v == x: return k print find_var(foo) Note that a value can have several different names (and unnamed references) pointing at it, so the above code is not very general, but it may illustrate some interesting points. My guess is that your entire approach may need rethinking. What is the ultimate objective of your project? Thank you for reading this far. If you were now to start writing, I'd be very grateful indeed. -- http://mail.python.org/mailman/listinfo/python-list
Re: Can I get a value's name
jalanb3 wrote: ... Given a variable name I can use locals() to get the value Is there a way to do it the other way round Given the value, can I get the variable name ? (1) Yes you can in some cases. (2) You should not, things do not inherently have a name. With that prelude: def find_names(value, dictionary): for name, val in dictionary.items(): if val is value: # note: is, not == yield name x = 123456 y = 123456 * 3 // 3 z = 123456.0 q = y print list(find_names(y, locals())) --Scott David Daniels scott.dani...@acm.org -- http://mail.python.org/mailman/listinfo/python-list
Re: Can I get a value's name
On Mon, 11 May 2009, jalanb3 wrote: [...] def replace_line(pattern,replacement): errors = '\n' in pattern and [ 'pattern' ] or [] errors += '\n' in replacement and [ 'replacement' ] or [] values = [ locals()[e] for e in errors ] # etc, etc, and eventually: print 'Argument %s is bad : %s' % (errors[0],values[0]) And the question arises from that locals() line: Given a variable name I can use locals() to get the value Is there a way to do it the other way round Given the value, can I get the variable name ? For example, suppose I had started like this (using the variables, not strings with their names) def replace_line(pattern,replacement): values = '\n' in pattern and [ pattern ] or [] values += '\n' in replacement and [ replacement ] or [] Can I later get the name pattern via values[0]? [...] def replace_line(pattern,replacement): values = '\n' in pattern and [ pattern ] or [] values += '\n' in replacement and [replacement] or [] loc=locals() print [i for i in loc if loc[i] is pattern if pattern in values] will print ['pattern'] if the value of pattern is in values (if there's a newline in pattern). Is that what you're after? HTH, John -- http://mail.python.org/mailman/listinfo/python-list
Re: Can I get a value's name
Thank you Ken for your help answer On Mon, May 11, 2009 at 8:11 PM, Ken Seehart k...@seehart.com wrote: jalanb3 wrote: snip def replace_line(pattern,replacement): values = '\n' in pattern and [ pattern ] or [] values += '\n' in replacement and [ replacement ] or [] Can I later get the name pattern via values[0]? snip A value generally does not contain the pattern or any kind of name information (although class, method, and function instances contain some symbolic information in them). That's why I took the question seriously at all: It was an entirely different project - pulling info out of tracebacks into logs. And I can get names from a reference for classes, modules, ... Why not variables ? Study the concept of 'references' and all of this will become more clear. I shall dive into that koan :-) The only way to do something like what you want would be to search globals() or locals() for the value (depending on the context), but that would be an extremely ugly hack. Agreed Chances are that if you want to do this, you need to rethink the problem instead. That does seem reasonable, but before I started writing Python it would never occurred to me to add some attributes on to an object whose definition I've never seen. So - unlikely, but I wouldn't rule it out. snip Note that a value can have several different names (and unnamed references) pointing at it, Ah - there's the rub ! All it takes (from my earlier example) is fred = pattern values += [ fred ] Now which is the real name of values[0]? In my example I would have wanted pattern, and now whatever ugly hack we used to get at the name is turning into an complex module. so the above code is not very general, but it may illustrate some interesting points. Thanks - it does indeed. My guess is that your entire approach may need rethinking. What is the ultimate objective of your project? Find out what some other Pythonista have thought about this problem OTOH: the actual objective was to remove the redundancy of using the string pattern when I already have a perfectly good eponymous variable. On balance I think allowing a little bit of redundancy is prudent in this case :-) -- http://mail.python.org/mailman/listinfo/python-list