Python中函数的别名

时间:2012-07-18 17:33:43

标签: python introspection

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

我的直觉说我能做到这一点,但我无法理解。任何蟒蛇大师在那里?

2 个答案:

答案 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()

是否应打印funcfunc_in_func_wrapperfunc_labelfunc_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']

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