关于python:从别名函数内确定函数名

Determine function name from within an aliased function

如何确定是使用函数名还是通过函数别名调用函数?

我可以通过执行以下操作来检查函数,从函数体中获取其名称:

1
2
3
4
5
6
import inspect

def foo():
   print(inspect.stack()[0][3])

foo() # prints 'foo'

源:从该函数内确定函数名(不使用回溯)

但是,如果对函数进行别名并尝试相同的操作,则会得到原始函数名(而不是别名)。

1
2
bar = foo
bar() # prints 'foo'

我希望能够做到以下几点:

1
2
3
4
5
6
7
def foo():
    print(... some code goes here ...)

bar = foo

foo() # prints 'foo'
bar() # prints 'bar'


基于我对你问题范围的有限了解,这是可行的:

1
2
3
4
5
6
7
8
import inspect

def foo():
  print(inspect.stack()[1][4][0].strip())

foo()
bar = foo
bar()

结果:

1
2
foo()
bar()


我有一个(有点黑客)解决方案,它依赖regex从字符串中解析函数名。可能有一个更清洁的解决方案,但至少使用inspect only这是我能找到的最好的解决方案。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import inspect
import re


function_from_call = re.compile("\w+(?=\(\))")


def foo():
    _, call_frame, *_ = inspect.stack()
    _, _, _, _, call, *_ = call_frame
    print(re.search(function_from_call, str(call)).group())

bar = foo
bar()  # prints bar
foo()  # prints foo

简短解释:首先,我抓取导致调用此函数的调用的检查帧。然后,我从这个框架中提取实际的调用字符串,并将regex应用于这个只提供函数名的调用字符串。

注意:在解释器外壳中,inspect的行为不同,上面的代码会产生错误,因为我的regex不能匹配实际的函数名。@user2357112在对这个问题的评论中指出了另外一个注意事项:显然,调用与名称直接相关,如

1
l = [foo]; l[0]()

当从脚本运行时,我的解决方案将正确地处理简单的重命名案例(如本问题中给出的案例),但我不提倡使用它,因为上面的角案例会导致混淆的错误。