如何获取list.sort()调用的帧数据?调用该方法时获取帧信息遇阻
如何追踪list.sort调用的栈帧信息
我懂你现在的困扰——想通过inspect模块抓到list.sort调用的帧信息,但目前的栈帧只能追到inner和outer,完全看不到sort的影子,对吧?
问题根源
其实原因很直接:list.sort是Python的内置方法,由C语言实现。当Python代码调用这类内置方法时,它不会在Python层面的调用栈中生成对应的帧记录。inspect模块只能追踪到纯Python代码的栈帧,所以你只能看到调用sort的inner函数,以及更上层的outer,却看不到sort本身的帧。
你原代码的输出应该是这样的:
calm_pear inner outer
这完全符合预期,因为C实现的方法不会出现在Python的调用栈里。
解决方案:用Python封装一层sort
如果一定要追踪到“某个排序函数调用了key函数”的栈帧信息,最简单的办法是自己用Python封装一个排序函数,替代原生的list.sort。比如:
import inspect def calm_pear(x): cur_frame = inspect.currentframe() out_frames = inspect.getouterframes(cur_frame) for idx, frame in enumerate(out_frames): print(f"out_frames[{idx}].function = '{frame.function}'") return id(x) # 用Python封装自己的sort方法 def python_sort(lst, key=None): # 内部用sorted实现排序逻辑,再把结果赋值回原列表 sorted_list = sorted(lst, key=key) lst[:] = sorted_list def outer(): inner() def inner(): [0, 1].sort(key=calm_pear) # 原生sort,看不到帧 print("---分割线---") lst = [0, 1] python_sort(lst, key=calm_pear) # 自定义Python实现,能看到帧 outer()
运行这段代码,你会在分割线后的输出里看到python_sort的帧:
calm_pear inner outer ---分割线--- calm_pear python_sort inner outer
这样就能清晰追踪到排序函数调用key函数的栈帧关系了。
额外说明
如果一定要追踪C层面的调用栈,那得用到更底层的调试工具(比如GDB),但这已经超出了Pythoninspect模块的能力范围,对于日常Python开发来说也没必要。用Python封装一层的方式完全能满足你追踪调用关系的需求。
内容的提问来源于stack exchange,提问作者Toothpick Anemone
相关产品推荐
相关产品推荐

