Reputation: 16610
Is there a way to know, during run-time, a variable's name (from the code)? Or do variable's names forgotten during compilation (byte-code or not)?
e.g.:
>>> vari = 15 >>> print vari.~~name~~() 'vari'
Note: I'm talking about plain data-type variables (int
, str
, list
etc.)
Upvotes: 35
Views: 29172
Reputation: 31828
Just yesterday I saw a blog post with working code that does just this. Here's the link:
Upvotes: 0
Reputation: 69
Nice easy solution using f-string formatting, which is native to Python 3.6 and later:
vari = 15
vari_name = f"{vari=}".split("=")[0]
print(vari_name)
Produces:
vari
Upvotes: 3
Reputation: 761
here a basic (maybe weird) function that shows the name of its argument... the idea is to analyze code and search for the calls to the function (added in the init method it could help to find the instance name, although with a more complex code analysis)
def display(var):
import inspect, re
callingframe = inspect.currentframe().f_back
cntext = "".join(inspect.getframeinfo(callingframe, 5)[3]) #gets 5 lines
m = re.search("display\s+\(\s+(\w+)\s+\)", cntext, re.MULTILINE)
print m.group(1), type(var), var
please note: getting multiple lines from the calling code helps in case the call was split as in the below example:
display(
my_var
)
but will produce unexpected result on this:
display(first_var)
display(second_var)
If you don't have control on the format of your project you can still improve the code to detect and manage different situations...
Overall I guess a static code analysis could produce a more reliable result, but I'm too lazy to check it now
Upvotes: 3
Reputation: 10650
You can do it, it's just not pretty.
import inspect, sys
def addVarToDict(d, variable):
lineNumber = inspect.currentframe().f_back.f_lineno
with open(sys.argv[0]) as f:
lines = f.read().split("\n")
line = lines[lineNumber-1]
varName = line.split("addVarToDict")[1].split("(")[1].split(",")[1].split(")")[0].strip()
d[varName] = variable
d = {}
a=1
print d # {}
addVarToDict(d,a)
print d # {'a': 1}
Upvotes: 2
Reputation: 1777
Here is a function I use to print the value of variables, it works for local as well as globals:
import sys
def print_var(var_name):
calling_frame = sys._getframe().f_back
var_val = calling_frame.f_locals.get(var_name, calling_frame.f_globals.get(var_name, None))
print (var_name+':', str(var_val))
So the following code:
global_var = 123
def some_func():
local_var = 456
print_var("global_var")
print_var("local_var")
print_var("some_func")
some_func()
produces:
global_var: 123
local_var: 456
some_func: <function some_func at 0x10065b488>
Upvotes: 4
Reputation: 39
This will work for simple data types (str, int, float, list etc.)
def my_print(var_str) :
print var_str+':', globals()[var_str]
Upvotes: 3
Reputation:
I tried the following link from the post above with no success: Googling returned this one.
http://pythonic.pocoo.org/2009/5/30/finding-objects-names
Upvotes: 1
Reputation: 8972
Variable names don't get forgotten, you can access variables (and look which variables you have) by introspection, e.g.
>>> i = 1
>>> locals()["i"]
1
However, because there are no pointers in Python, there's no way to reference a variable without actually writing its name. So if you wanted to print a variable name and its value, you could go via locals()
or a similar function. ([i]
becomes [1]
and there's no way to retrieve the information that the 1
actually came from i
.)
Upvotes: 35
Reputation: 881675
Variable names persist in the compiled code (that's how e.g. the dir
built-in can work), but the mapping that's there goes from name to value, not vice versa. So if there are several variables all worth, for example, 23
, there's no way to tell them from each other base only on the value 23
.
Upvotes: 12