我想找到被调用函数的名称...即调用函数的变量的名称。使用基本配方,例如__name__
,func_name
或检查基本堆栈对我不起作用。例如
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"
我的直觉说我能做到这一点,但我无法理解。任何蟒蛇大师在那里?
答案 0 :(得分:1)
这里的问题是间接的。您可能会做一些复杂的事情,比如检查堆栈,获取调用函数的模块的代码,从堆栈中解析行号以找到用于在本地上下文中调用函数的标签,然后使用它,但是不一定会给你你想要的东西。考虑:
def func(x):
print get_label_function_called_with()
def func_wrapper(func_in_func_wrapper):
return func_in_func_wrapper
func_label = func
func_from_func_wrapper = func_wrapper(func_label)
func_from_func_wrapper()
是否应打印func
,func_in_func_wrapper
,func_label
或func_from_func_wrapper
?一开始看起来似乎是一个明显的答案,但鉴于你真的不知道你所调用的代码内部会出现什么样的间接,你真的无法确定。
答案 1 :(得分:1)
这可能是不可能100%正确地执行此操作,但您可以尝试以下方法:
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()
这将打印:
['a']
['a', 'b']
['a', 'b']
['a']
['b']
它非常丑陋和复杂,但可能适合您的需要。它的工作原理是找到调用此函数的行中使用的所有变量,并将它们与当前函数进行比较。