I am reading codes

通过打印调用栈研究代码

Posted on By kennethxian

在阅读开源代码时,我们常常想捋一捋关键逻辑的调用关系,了解一下比如当前的代码段是通过什么样的路径被调用的。在Python中,可以通过sys._getframe()达到这一目的。

比如用如下的两个Python文件做例子:

  1. test.py:
#!/usr/bin/python
# coding: utf-8
import printStack

def main():
    printStack.moduleFun()

if __name__ == "__main__":
    main()
  1. printStack.py:
#!/usr/bin/python
# coding: utf-8

def moduleFun():
    print('It is a good day today!')

这是个简单的通过函数调用打印一句话的例子,假如此时,我们想知道printStack.py中的moduleFun是如何被调用到的,将printStack.py修改成如下:

#!/usr/bin/python
# coding: utf-8
import sys

def printStackFun():
    frame = sys._getframe().f_back
    while frame:
        print(frame.f_code.co_filename + ':' + frame.f_code.co_name + ':' + str(frame.f_lineno))
        frame = frame.f_back

def moduleFun():
    print('It is a good day today!')
    printStackFun()

在moduleFun中加入printStackFun,在后者中,使用sys._getframe()打印出函数被调用时的栈信息。

执行test.py,我们将看到如下输出:

[root ~]# python test.py
It is a good day today!
/root/printStack.py:moduleFun:13
test.py:main:6
test.py:<module>:9

我的代码放在/root目录下,从这里的输出可以看出,函数调用经历的文件名、方法名以及代码行号。

抛砖引玉,当您遇到感兴趣的代码而希望了解它被调用的细节时,这是个不错的方法。