如何在Python静态方法中获取调用者函数对象?
获取静态方法的准确调用者类与方法名
可行实现方案
利用inspect模块获取调用栈帧的代码对象,通过匹配代码对象找到对应的函数实例,从而获取完整的__qualname__:
import inspect class A: @staticmethod def f(): # 跳过当前栈帧,获取调用者的栈帧 caller_frame = inspect.stack()[1] try: caller_code = caller_frame.frame.f_code # 遍历全局变量,匹配代码对象找到对应函数 for _, obj in globals().items(): if hasattr(obj, "__code__") and obj.__code__ is caller_code: print(obj.__qualname__) break finally: # 强制删除栈帧引用,避免内存泄漏 del caller_frame class B: @staticmethod def f(): A.f() class C: @staticmethod def f(): A.f() B.f() # 输出: B.f C.f() # 输出: C.f
核心原理
每个函数的__code__属性是唯一的代码对象,通过对比栈帧中的f_code与全局变量中函数的__code__,可以精准定位到调用者函数,再通过__qualname__直接获取类+方法的完整名称,避免了仅靠函数名无法区分的问题。
性能优化方案
如果全局变量较多,遍历查找的效率可以通过提前构建代码对象到函数的映射来优化:
import inspect # 预构建代码对象到函数的映射表 code_func_map = {} for name, obj in globals().items(): if hasattr(obj, "__code__"): code_func_map[obj.__code__] = obj class A: @staticmethod def f(): caller_frame = inspect.stack()[1] try: caller_code = caller_frame.frame.f_code print(code_func_map[caller_code].__qualname__) finally: del caller_frame # B、C类及调用代码同上
边界情况说明
- 若调用者是局部函数或嵌套函数,需要将遍历范围从
globals()改为调用栈帧的f_locals。 - 动态生成的函数(如
exec创建)需要同步更新映射表,否则无法匹配。
内容的提问来源于stack exchange,提问作者sl2c
相关产品推荐
相关产品推荐

