1

我想找到函数的名称,因为它被称为......即调用函数的变量的名称。使用基本配方,即使用__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"

我的直觉说我可以做到这一点,但我无法弄清楚。有没有蟒蛇大师?

4

2 回答 2

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? 乍一看,这似乎是一个显而易见的答案,但鉴于您永远不知道您正在调用的代码内部发生了哪种间接,您真的无法确定。

于 2012-07-18T18:07:20.770 回答
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']

它非常丑陋和复杂,但可能适合您的需要。它通过查找调用此函数的行中使用的所有变量并将它们与当前函数进行比较来工作。

于 2012-07-18T18:27:59.517 回答