在运行时识别python脚本行中的函数调用
问题描述:
我有一个用'exec'运行的python脚本。 当脚本调用某个函数时,我希望它知道该调用的行号和偏移量。在运行时识别python脚本行中的函数调用
这里是一个例子。如果我的脚本是:
foo1(); foo2(); foo1()
foo3()
如果我在每一个功能的代码,打印(行偏移),我应该得到
(0,0), (0,8), (0,16), (1,0)
在大多数情况下,这可以通过获取堆栈中轻松完成帧,因为它包含行号和函数名称。唯一的问题是在某一行中有两个具有相同名称的函数。不幸的是,这是我常见的情况。有任何想法吗?
好吧,改变原来的代码似乎是最简单的解决方案。
你将如何解决的事情就像
if foo1(7) or foo1(6):
或
foo2(foo1(), foo1())
这有一些不是很优雅的解决方案,例如,在前面的例子自动转向:
def curpos(pos, func):
record_curpos(pos)
return func
curpos(foo2,0)(curpos(foo1,5)(), curpos(foo1,13)())
让我知道你是否有更简单的想法。
答
Python不提供大量有关字符偏移的信息。
如果您使用exec来执行Python,那么您可以在执行它之前以机械方式重新编写代码,以告诉您想知道什么。例如,你可以改变原来的代码:
foo1(); foo2(); foo1()
foo3()
到注释代码:
curpos(1,0); foo1(); curpos(1,8); foo2(); curpos(1,16); foo1()
curpos(2,0); foo3()
,然后执行的是注释的代码。
其中curpos(line,char)
记录或打印原始代码中该点的行和字符信息。这将比堆栈框架简单得多。
答
当然,你可以看看字符串中的线,并试图找到函数名,尽管这将是不可靠的,如果他们别名功能,如:
bar = foo2
foo1(); foo2()
否则,它变得非常困难。 coverage模块是这样做的,Ned解释了特定技术in a blog post - 基本上它涉及重写字节码以将表达式分离成不同的(伪)行号。
您可能实际上可以使用coverage模块本身。
实际上,字节码重写是在另一个帖子中:http://nedbatchelder.com/blog/200804/wicked_hack_python_bytecode_tracing。HTML(我不必诉诸于此获得分支机构覆盖)。 – 2010-05-13 22:33:59
谢谢!看起来非常相关(并且很有趣) – Dani 2010-05-14 15:11:09