可以从任何代码对象(和扩展模块/内置)调用:从
exec,
execfile在模块名称空间(在导入期间),在类定义内,在方法/类方法/静态方法内,从修饰的函数/方法内,从嵌套函数中…,因此通常没有“调用函数”,并且很难做到这一点。
堆栈框架及其代码对象是最常用的-检查属性。
在许多情况下,这可以找到调用函数:
import sys, inspectdef get_calling_function(): """finds the calling function in many decent cases.""" fr = sys._getframe(1) # inspect.stack()[1][0] co = fr.f_pre 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.__pre__ == co: return func raise AttributeError("func not found")# Usagedef 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>>



