2010-05-13 70 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