我想对任何函数/方法做一些反省。对于我的所有示例,我都使用Python2.7,但是如果使用3.3可以简化一些事情,那么使用3.3就不是问题了。在
假设我在一个名为foobar.py公司名称:
def foo():
bar()
我可以看到foo动态运行的代码:
^{pr2}$我还可以从该函数的code对象获取反汇编的字节码:
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
和{inspect
和dis
崩溃时,它所到达的CPython代码可能会很有趣。然而,我甚至不确定这是否可能。在
所有编译器/解释器在解析源代码时都会构建一个抽象语法树。这是一个基于上下文无关语法的程序表示,然后可以递归遍历生成可由机器执行的代码。在
Python提供了对AST的访问,您可以自己遍历这个树并在
ast.FunctionDef
中查找ast.Call
对象。下面是一个简单的例子。请注意,这肯定不会捕获所有可能的调用,因为调用可以嵌入到其他表达式中,由eval
表达式等隐藏。下面是一个简单的示例:一个例子:
^{pr2}$相关问题 更多 >
编程相关推荐