2010-05-13 95 views
2

我有一个用'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)()) 

让我知道你是否有更简单的想法。

回答

1

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)记录或打印原始代码中该点的行和字符信息。这将比堆栈框架简单得多。

0

当然,你可以看看字符串中的线,并试图找到函数名,尽管这将是不可靠的,如果他们别名功能,如:

bar = foo2 
foo1(); foo2() 

否则,它变得非常困难。 coverage模块是这样做的,Ned解释了特定技术in a blog post - 基本上它涉及重写字节码以将表达式分离成不同的(伪)行号。

您可能实际上可以使用coverage模块本身。

+0

实际上,字节码重写是在另一个帖子中:http://nedbatchelder.com/blog/200804/wicked_hack_python_bytecode_tracing。HTML(我不必诉诸于此获得分支机构覆盖)。 – 2010-05-13 22:33:59

+0

谢谢!看起来非常相关(并且很有趣) – Dani 2010-05-14 15:11:09