Python中函数的别名

Python中函数的别名,python,introspection,Python,Introspection,我想找到调用的函数的名称。。。i、 e.调用函数的变量的名称。使用基本配方,即使用\uuuu name\uuuu、func\u 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

我想找到调用的函数的名称。。。i、 e.调用函数的变量的名称。使用基本配方,即使用
\uuuu name\uuuu
func\u 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"

我的直觉告诉我可以做到,但我想不出来。有python大师吗?

这里的问题是间接性。您可能会做一些复杂的事情,比如检查堆栈,获取调用函数的模块的代码,解析堆栈中的行号,找到用于在本地上下文中调用函数的标签,然后使用它,但这并不一定能满足您的需要。考虑:

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\u包装中的func\u
func\u标签
,或从func\u包装中打印
func\u?乍一看,这似乎是一个显而易见的答案,但考虑到您从未真正知道您正在调用的代码内部正在进行何种间接寻址,您确实无法确定。

可能无法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()

这很难看也很复杂,但可能满足你的需要。它的工作原理是找到调用此函数的行中使用的所有变量,并将它们与当前函数进行比较。

我怀疑这是否可行。你想这样做有什么特别的原因吗?通常当人们问如何做这样的事情时,他们正在做一些非常糟糕的事情。你们能解释一下这有什么用吗?你们可以更改零件的名称,但我不明白你们为什么要这么做。另外,请查看decorator文档。
func\u name
是在创建函数时定义的
a.func\u name
somefunc
。这是不可能的。函数只有一个规范名称,即用于构造它的名称(在
def
语句中指定,并存储在其
func\u名称
\u名称
属性中)。您可以有任意数量的其他标识符指向它,但无法从用于调用它的函数内部进行判断。这是一个复杂的情况,在我的情况下,我不关心包装器,但其他人可能关心包装器。问题是,这就是为什么没有简单甚至真正可行的方法来实现这一点。可能不快/不可行,但我的问题是是否有可能。。。我确信有一种方法比python中的选定答案更加健壮,因为python是真正动态的。我喜欢这一点,这是我试图编写的内容的精髓。。。正如你所说,这很复杂。因为解析器给出了一个语法错误,所以我不能真正分配返回值,所以我可以在a()函数中使用它。虽然下一个挑战将是一个更简单的解决方案,但您的答案符合我的要求!谢谢
['a']
['a', 'b']
['a', 'b']
['a']
['b']