How can you print a variable name in python?

218,741

Solution 1

If you insist, here is some horrible inspect-based solution.

import inspect, re

def varname(p):
  for line in inspect.getframeinfo(inspect.currentframe().f_back)[3]:
    m = re.search(r'\bvarname\s*\(\s*([A-Za-z_][A-Za-z0-9_]*)\s*\)', line)
    if m:
      return m.group(1)

if __name__ == '__main__':
  spam = 42
  print varname(spam)

I hope it will inspire you to reevaluate the problem you have and look for another approach.

Solution 2

To answer your original question:

def namestr(obj, namespace):
    return [name for name in namespace if namespace[name] is obj]

Example:

>>> a = 'some var'
>>> namestr(a, globals())
['a']

As @rbright already pointed out whatever you do there are probably better ways to do it.

Solution 3

If you are trying to do this, it means you are doing something wrong. Consider using a dict instead.

def show_val(vals, name):
    print "Name:", name, "val:", vals[name]

vals = {'a': 1, 'b': 2}
show_val(vals, 'b')

Output:

Name: b val: 2

Solution 4

You can't, as there are no variables in Python but only names.

For example:

> a = [1,2,3]
> b = a
> a is b
True

Which of those two is now the correct variable? There's no difference between a and b.

There's been a similar question before.

Solution 5

Rather than ask for details to a specific solution, I recommend describing the problem you face; I think you'll get better answers. I say this since there's almost certainly a better way to do whatever it is you're trying to do. Accessing variable names in this way is not commonly needed to solve problems in any language.

That said, all of your variable names are already in dictionaries which are accessible through the built-in functions locals and globals. Use the correct one for the scope you are inspecting.

One of the few common idioms for inspecting these dictionaries is for easy string interpolation:

>>> first = 'John'
>>> last = 'Doe'
>>> print '%(first)s %(last)s' % globals()
John Doe

This sort of thing tends to be a bit more readable than the alternatives even though it requires inspecting variables by name.

Share:
218,741

Related videos on Youtube

physicsmichael
Author by

physicsmichael

Particle physics in my rear view mirror; data science in my headlights. My mother tongue is python, but I used C++ often while I was stuck/blessed with ROOT in physics. I dabble in Tex, Arduino, Raspi, bash, cluster computing, and more!

Updated on July 08, 2022

Comments

  • physicsmichael
    physicsmichael almost 2 years

    Say I have a variable named choice it is equal to 2. How would I access the name of the variable? Something equivalent to

    In [53]: namestr(choice)
    Out[53]: 'choice'
    

    for use in making a dictionary. There's a good way to do this and I'm just missing it.

    EDIT:

    The reason to do this is thus. I am running some data analysis stuff where I call the program with multiple parameters that I would like to tweak, or not tweak, at runtime. I read in the parameters I used in the last run from a .config file formated as

    filename
    no_sig_resonance.dat
    
    mass_peak
    700
    
    choice
    1,2,3
    

    When prompted for values, the previously used is displayed and an empty string input will use the previously used value.

    My question comes about because when it comes to writing the dictionary that these values have been scanned into. If a parameter is needed I run get_param which accesses the file and finds the parameter.

    I think I will avoid the problem all together by reading the .config file once and producing a dictionary from that. I avoided that originally for... reasons I no longer remember. Perfect situation to update my code!

  • Kenan Banks
    Kenan Banks about 15 years
    The difference between a and b is the name.
  • dF.
    dF. about 15 years
    gs is right. a and b refer to the same object, so a function receiving this object has no way to know which name was used to refer to the object in the function call.
  • Kenan Banks
    Kenan Banks about 15 years
    He's kinda right, in that there is no way for you to write a function in Python to differentiate. Still, there's no reason there couldn't be a built-in function that accomplishes this.
  • physicsmichael
    physicsmichael about 15 years
    I want to try to and print 'first' and 'last', the values that I call the references, not what they are equal to.
  • Greg Hewgill
    Greg Hewgill about 15 years
    This fails if there is more than one variable name with the same value.
  • Greg Hewgill
    Greg Hewgill about 15 years
    This fails if there is more than one variable name referring to the same value.
  • jfs
    jfs about 15 years
    dis.dis() returns some names (not always).
  • jfs
    jfs about 15 years
    Therefore It is sometimes possible to distinguish between a and b even they're referring to the same object. Python scopes are static. Namespaces are dynamic.
  • jfs
    jfs about 15 years
    @Greg Hewgill: You might have noticed that namestr returns list. It is a hint that there could be more than one name.
  • jfs
    jfs about 15 years
    It means that e.g. when a function returns there might be no local namespace of that function left but you still may inspect the function code object to find what names are used inside.
  • jfs
    jfs about 15 years
    I'd say most integers don't share their representations.
  • physicsmichael
    physicsmichael about 15 years
    I like the flow of your answer code, but I may be working with integers that may be repeated several times in the code... sigh
  • user1066101
    user1066101 about 15 years
    +1: The original question is not sensible. It's a simple dictionary. Or -- perhaps -- use a different language.
  • B Bulfin
    B Bulfin about 15 years
    key = "choice"; print vals[key]
  • Piotr Dobrogost
    Piotr Dobrogost over 12 years
    @J.F.Sebastian I'd say most integers don't share their representations I'm pretty sure there is the same amount of each of these two kinds :) Both sets are countable.
  • jfs
    jfs over 12 years
    @Piotr Dobrogost: "share their representions" refers to CPython optimization that caches small integers therefore one of the sets is not countable it is finite.
  • jfs
    jfs over 11 years
    There is related use case for inspect.currentframe().f_back.f_locals
  • yantrab
    yantrab over 11 years
    "There are no variables in Python" Silly misinformation. You mean, "variables in Python work differently than in C."
  • Jake
    Jake about 10 years
    Sometimes a night of debugging makes us do things we're not proud of.
  • Enteleform
    Enteleform about 8 years
    upvoted for literal LOL
  • Waylon Walker
    Waylon Walker almost 7 years
    I like this solution the best, but did not like how '_' or '_70' would also show up. Unless you are searching fro private objects this provides a bit cleaner output. ``` def var_name(obj, namespace=globals()): return [name for name in namespace if namespace[name] is obj and name[0] != '_'][0] ```
  • M. Lautaro
    M. Lautaro over 4 years
    I like how Jake's comment comes 5 years after the question and yet it still has 70+ up votes of people that, like me, reluctantly searched how to do this shameless thing in a moment of desperation

Related