Python如何获取调用函数(不仅仅是其名称)?
我想编写一个返回调用函数的函数:
def foo():
return get_calling_function() #should return 'foo' function object
在线上有许多示例,这些示例如何获取调用函数的 名称
,而不是如何获取实际对象。我提出了以下解决方案,该解决方案获取名称,然后在调用函数的全局名称空间中查找它。但是,这对于类函数不起作用,因为在那里您还需要类名,并且我想像还有很多其他的边缘情况。
from inspect import stack
def get_calling_function():
return stack()[2][0].f_globals[stack()[1][3]]
因此,是否有任何建议如何或是否有可能编写此函数以使其能够正常运行(在Python 3上,btw)?谢谢。
-
可以从任何代码对象(和扩展模块/内置)调用:从
exec
,execfile
在模块名称空间(在导入期间),在类定义内,在方法/类方法/静态方法内,从修饰的函数/方法内,从嵌套函数中…,因此通常没有“调用函数”,并且很难做到这一点。堆栈框架及其代码对象是最常用的-检查属性。
在许多情况下,这可以找到调用函数:
import sys, inspect def get_calling_function(): """finds the calling function in many decent cases.""" fr = sys._getframe(1) # inspect.stack()[1][0] co = fr.f_code for get in ( lambda:fr.f_globals[co.co_name], lambda:getattr(fr.f_locals['self'], co.co_name), lambda:getattr(fr.f_locals['cls'], co.co_name), lambda:fr.f_back.f_locals[co.co_name], # nested lambda:fr.f_back.f_locals['func'], # decorators lambda:fr.f_back.f_locals['meth'], lambda:fr.f_back.f_locals['f'], ): try: func = get() except (KeyError, AttributeError): pass else: if func.__code__ == co: return func raise AttributeError("func not found") # Usage def f(): def nested_func(): print get_calling_function() print get_calling_function() nested_func() class Y: def meth(self, a, b=10, c=11): print get_calling_function() class Z: def methz(self): print get_calling_function() z = Z() z.methz() return z @classmethod def clsmeth(cls): print get_calling_function() @staticmethod def staticmeth(): print get_calling_function() f() y = Y() z = y.meth(7) z.methz() y.clsmeth() ##y.staticmeth() # would fail
它发现:
<function f at 0x012E5670> <function nested_func at 0x012E51F0> <bound method Y.meth of <__main__.Y instance at 0x01E41580>> <bound method Z.methz of <__main__.Z instance at 0x01E63EE0>> <bound method Z.methz of <__main__.Z instance at 0x01E63EE0>> <bound method classobj.clsmeth of <class __main__.Y at 0x01F3CF10>>