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