Can I get a value's name

Ken Seehart ken at
Mon May 11 21:11:22 CEST 2009

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.

More information about the Python-list mailing list