This thread discusses how to get the name of a function as a string in Python: How to get a function name as a string?
How can I do the same for a variable? As oppose
Even if variable values don't point back to the name, you have access to the list of every assigned variable and its value, so I'm astounded that only one person suggested looping through there to look for your var name.
Someone mentioned on that answer that you might have to walk the stack and check everyone's locals and globals to find foo
, but if foo
is assigned in the scope where you're calling this retrieve_name
function, you can use inspect
's current frame
to get you all of those local variables.
My explanation might be a little bit too wordy (maybe I should've used a "foo" less words), but here's how it would look in code (Note that if there is more than one variable assigned to the same value, you will get both of those variable names):
import inspect
x,y,z = 1,2,3
def retrieve_name(var):
callers_local_vars = inspect.currentframe().f_back.f_locals.items()
return [var_name for var_name, var_val in callers_local_vars if var_val is var]
print retrieve_name(y)
If you're calling this function from another function, something like:
def foo(bar):
return retrieve_name(bar)
foo(baz)
And you want the baz
instead of bar
, you'll just need to go back a scope further. This can be done by adding an extra .f_back
in the caller_local_vars
initialization.
See an example here: ideone
In Python, the def
and class
keywords will bind a specific name to the object they define (function or class). Similarly, modules are given a name by virtue of being called something specific in the filesystem. In all three cases, there's an obvious way to assign a "canonical" name to the object in question.
However, for other kinds of objects, such a canonical name may simply not exist. For example, consider the elements of a list. The elements in the list are not individually named, and it is entirely possible that the only way to refer to them in a program is by using list indices on the containing list. If such a list of objects was passed into your function, you could not possibly assign meaningful identifiers to the values.
Python doesn't save the name on the left hand side of an assignment into the assigned object because:
So, for example, functions defined using lambda
will always have the "name" <lambda>
, rather than a specific function name.
The best approach would be simply to ask the caller to pass in an (optional) list of names. If typing the '...','...'
is too cumbersome, you could accept e.g. a single string containing a comma-separated list of names (like namedtuple
does).
Maybe this could be useful:
def Retriever(bar):
return (list(globals().keys()))[list(map(lambda x: id(x), list(globals().values()))).index(id(bar))]
The function goes through the list of IDs of values from the global scope (the namespace could be edited), finds the index of the wanted/required var or function based on its ID, and then returns the name from the list of global names based on the acquired index.
For constants, you can use an enum, which supports retrieving its name.
I try to get name from inspect locals, but it cann't process var likes a[1], b.val. After it, I got a new idea --- get var name from the code, and I try it succ! code like below:
#direct get from called function code
def retrieve_name_ex(var):
stacks = inspect.stack()
try:
func = stacks[0].function
code = stacks[1].code_context[0]
s = code.index(func)
s = code.index("(", s + len(func)) + 1
e = code.index(")", s)
return code[s:e].strip()
except:
return ""