Python 从别名函数中确定函数名
如何确定函数是使用函数名调用的,还是通过该函数的别名调用的 通过执行以下操作,我可以检查函数以从函数体中获取其名称:Python 从别名函数中确定函数名,python,python-3.x,introspection,Python,Python 3.x,Introspection,如何确定函数是使用函数名调用的,还是通过该函数的别名调用的 通过执行以下操作,我可以检查函数以从函数体中获取其名称: import inspect def foo(): print(inspect.stack()[0][3]) foo() # prints 'foo' 资料来源: 但是,如果我对函数使用别名并尝试相同的操作,则会得到原始函数名(而不是别名) 我希望能够做到以下几点: def foo(): print(... some code goes here ...)
import inspect
def foo():
print(inspect.stack()[0][3])
foo() # prints 'foo'
资料来源:
但是,如果我对函数使用别名并尝试相同的操作,则会得到原始函数名(而不是别名)
我希望能够做到以下几点:
def foo():
print(... some code goes here ...)
bar = foo
foo() # prints 'foo'
bar() # prints 'bar'
我有一个(有点黑)解决方案,它依赖正则表达式从字符串中解析函数名。可能有一个更干净的解决方案,但至少使用inspect only这是我能找到的最好的解决方案
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
简要说明:首先,我抓取导致调用此函数的调用的inspect帧。然后,我从这个框架中提取实际的调用字符串,并对这个调用字符串应用一个正则表达式,它只给出函数名
注意:在解释器shell中,inspect的行为不同,上面的代码产生错误,因为我的正则表达式无法匹配实际的函数名。@user2357112在对这个问题的评论中指出了一个额外的警告:一个调用与一个名称直接关联并不明显,比如
l = [foo]; l[0]()
当从脚本运行时,我的解决方案将正确处理简单的重命名情况(如本问题中给出的情况),但我不主张使用它,因为上述情况会导致混乱的错误。基于我对问题范围的有限了解,这是可行的:
import inspect
def foo():
print(inspect.stack()[1][4][0].strip())
foo()
bar = foo
bar()
结果:
foo()
bar()
我真的很好奇看到这个工作!但是你的regexp对我来说不匹配,这很奇怪。您是否完全按照此处提供的方式使用了我的代码?我得到了评论的打印输出。我正在使用Python 3.5.2。以防这会影响到它。。编辑并注意:我不确定我的regexp是否可以按原样处理任意命名的函数(这就是我在上面称之为“hack”的原因)。我使用的是Python 3.6.2,inspect模块可能略有不同,当我使用inspect.stack()时,正如所料,函数名仍然是foo。我在pyenv中安装了python3.6.2,但是用它运行脚本仍然会得到我描述的输出。但是请注意,@JacobIRR的答案(它绕过了regex)使用了与我相同的inspect访问权限。不能保证用于调用函数的引用是从任何名称获得的。它可能是
l=[foo];l[0]()
或排序(一些列表,key=l[0])
。这是一个好的观点,我想在这种情况下l[0]()
应该打印l[0]
。这对我来说会引发一个“非类型不可订阅”错误。我可以改为使用inspect.stack()[0][3]使其工作,但它仍然返回'foo'。你知道如何才能真正做到这一点吗?它在解释器中不起作用,但作为脚本起作用。谢谢,这对我来说很有用(在解释器中以及在python3.6的脚本中),并且还有另外一个好处,就是在括号中给出参数。@OlivierMelançon,恶心。。看来解决这个问题的任何方法都是很难的。我唯一能想到的另一件事是循环遍历堆栈的所有部分,如果函数名不是原始名称,但仍然是hack@JacobIRR事实上,我真的很惊讶,你能让它像现在这样工作,干得好!
foo()
bar()