如何在Python中获取调用函数栈帧的一致内存地址?
解决inspect模块获取caller栈帧地址不一致的问题
尝试用Python的inspect模块获取函数栈的帧地址时,发现调用函数caller在两个不同内部函数中的帧地址输出不一致。演示代码如下:
import inspect def inner_function1(): for frame_info in inspect.stack()[:2]: print(frame_info.function, hex(id(frame_info))) def inner_function2(): for frame_info in inspect.stack()[:2]: print(frame_info.function, hex(id(frame_info))) def caller(): inner_function1() print(30*"-") inner_function2() caller()
实际输出结果:
inner_function1 0x786436cfb2e0 caller 0x786436cfb3a0 ------------------------------ inner_function2 0x786436cfb3a0 caller 0x786436cfb2e0
期望输出结果:
inner_function1 0x786436cfb2e0 caller 0x786436cfb3a0 ------------------------------ inner_function2 0x786436cfb3a0 caller 0x786436cfb3a0
问题出在你获取的是FrameInfo对象的ID,而非实际栈帧的ID。每次调用inspect.stack()都会生成新的FrameInfo实例,所以即使指向同一个栈帧,这些实例的内存地址也会不同。
要获取真正的栈帧对象,需要访问FrameInfo的frame属性,它指向底层的栈帧对象。在同一个caller函数调用过程中,两次内部函数调用共享同一个caller栈帧,因此id(frame_info.frame)会保持一致。
修改后的代码如下:
import inspect def inner_function1(): for frame_info in inspect.stack()[:2]: print(frame_info.function, hex(id(frame_info.frame))) def inner_function2(): for frame_info in inspect.stack()[:2]: print(frame_info.function, hex(id(frame_info.frame))) def caller(): inner_function1() print(30*"-") inner_function2() caller()
修改后输出结果示例:
inner_function1 0x7f8b1c04a140 caller 0x7f8b1c04a200 ------------------------------ inner_function2 0x7f8b1c04a320 caller 0x7f8b1c04a200
可以看到,两次输出中caller对应的栈帧地址完全一致。
内容的提问来源于stack exchange,提问作者Ramin Fakhimi
相关产品推荐
相关产品推荐

