I want to find the name of the function as it was called ... i.e. the name of the variable that called the function. Using the basic recipes i.e. with __name__
, func_name
, or inspecting the basic stack does not work for me. For example
def somefunc():
print "My name is: %s" % inspect.stack()[1][3]
a = somefunc
a()
# would output: out: "My name is: somefunc"
# whereas I want it to output: "My name is: a"
My gut says I can do this, but I can't figure it out. Any python guru's out there?
It's probably impossible to do this 100% correctly, but you could give the following a try:
import inspect
import parser
# this flatten function is by mike c fletcher
def flatten(l, ltypes=(list, tuple)):
ltype = type(l)
l = list(l)
i = 0
while i < len(l):
while isinstance(l[i], ltypes):
if not l[i]:
l.pop(i)
i -= 1
break
else:
l[i:i + 1] = l[i]
i += 1
return ltype(l)
# function we're interested in
def a():
current_func = eval(inspect.stack()[0][3])
last_frame = inspect.stack()[1]
calling_code = last_frame[4][0]
syntax_tree = parser.expr(calling_code)
syntax_tree_tuple = parser.st2tuple(syntax_tree)
flat_syntax_tree_tuple = flatten(syntax_tree_tuple)
list_of_strings = filter(lambda s: type(s)==str,flat_syntax_tree_tuple)
list_of_valid_strings = []
for string in list_of_strings:
try:
st = parser.expr(string)
list_of_valid_strings.append(string)
except:
pass
list_of_candidates = filter(lambda s: eval(s)==current_func, list_of_valid_strings)
print list_of_candidates
# other function
def c():
pass
a()
b=a
a(),b(),c()
a(),c()
c(),b()
This will print:
['a']
['a', 'b']
['a', 'b']
['a']
['b']
It's pretty ugly and complicated, but might work for what you need. It works by finding all variables used in the line that called this function and comparing them to the current function.