我想对任何函数/方法进行一些反省。对于我的所有示例,我都使用 Python 2.7,但是如果使用 3.3 可以使事情变得更容易,那么使用 3.3 不是问题。
假设我在名为 foobar.py 的模块中有以下代码:
def foo():
bar()
我可以看到 foo 运行的动态代码:
import inspect
import foobar
inspect.getsource(foobar.foo)
我还可以从这个函数的代码对象中获取反汇编的字节码:
import dis
dis.dis(foobar.foo)
有没有一种方法可以检测到该foo
方法调用了另一个函数(bar
在这种情况下),然后动态地反汇编/检查它?
我知道代码对象本身具有各种属性,如下所示:
>>> dir(foobar.foo.__code__)
['__class__', '__cmp__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_stacksize', 'co_varnames']
我检查了他们中的大多数,只是环顾四周,但还没有完全找到我要找的东西。
最终目标只是一个小实验,看看我是否可以在不执行导入以外的代码的情况下递归打印出一个可能的调用堆栈。我知道理论上的调用堆栈不能解释运行时的事情,比如特定变量的状态等。我只想打印出给定某个调用的所有嵌套函数的源代码(即使代码永远不会基于运行时状态)。
此外,我知道一旦我进入 CPython 代码,inspect
anddis
模块将无济于事。最终,打印出某种映射可能会很有趣,该映射显示它何时到达inspect
并dis
分解了 CPython 代码。但是,我什至不确定这是否可能。