2013-05-29 36 views
1

我的作品涉及Python代碼中的代碼片段的檢測。所以在我的工作中,我將在python中編寫一個腳本,以便將另一個python文件作爲輸入,並在腳本中插入必需的代碼。如何區分python中的「一個字符串」和「一個實際的代碼」?

下面的代碼是一個文件的示例代碼,我會被插裝:

A.py #normal un-instrumented code 

statements 
.... 
.... 

def move(self,a): 
    statements 
    ...... 
    print "My function is defined" 
    ...... 

statements 
...... 

我的劇本究竟做的是檢查在A.py每一行,如果有一個「高清」那麼代碼片段儀表上的代碼頂部的高清功能

下面的例子是最後出來放如何應該是:

A.py #instrumented code 

statements 
.... 
.... 

@decorator #<------ inserted code 
def move(self,a): 
    statements 
    ...... 
    print "My function is defined" 
    ...... 

statements 
...... 

但我已經導致不同輸出。下面的代碼是我得到的最終輸出:

A.py #instrumented代碼

statements 
.... 
.... 

@decorator #<------ inserted code 
def move(self,a): 
    statements 
    ...... 
    @decorator #<------ inserted code [this should not occur] 
    print "My function is defined" 
    ...... 

statements 
...... 

我可以理解,在改動的代碼它承認「高清」的「定義」類的話它在它上面提供了一個代碼。

實際上,檢測代碼有很多這些問題,我無法正確測量給定的python文件。有沒有其他方法來區分字符串的實際「def」?

謝謝

+0

你是如何在儀器中發現'def'的?如果使用正則表達式然後嘗試'r'\ bdef \ b''。 '\ b'標記一個字邊界。 – cdarke

+0

即使有這樣的聲明,它會工作「這是一個def」 – Kaushik

+0

沒有。要處理嵌入在引號中的文本,您需要消極的查找。 – cdarke

回答

3

使用ast module正確解析文件。

此代碼打印行數和列各def聲明的偏移:

import ast 
with open('mymodule.py') as f: 
    tree = ast.parse(f.read()) 
for node in ast.walk(tree): 
    if isinstance(node, ast.FunctionDef): 
     print node.lineno, node.col_offset 
+0

當我在def函數上方聲明一個語句時,如何使用列偏移值,使其與def函數正確對齊。 – Kaushik

+1

@karthik我不確定製表符如何影響'col_offset';試試看。我認爲你需要從行首開始拷貝'col_offset'字符並使用該字符串來縮進'@ decorator'。 –

0

你可以使用正則表達式。爲了避免def引號裏的話可以用負查找變通:

import re 

for line in open('A.py'): 
    m = re.search(r"(?!<[\"'])\bdef\b(?![\"'])", line) 
    if m: 
     print r'@decorator #<------ inserted code' 

    print line 

然而,有可能是其他def是occurances你我想不到的,如果我們不小心,我們最終向上重新編寫Python解析器。 @Janne Karila建議使用ast.parse從長遠來看可能更安全。

+1

然後有多行字符串。 –

+0

@JanneKarila:是的,這是我沒有想到的。這隻表明你的答案是首選。 – cdarke

相關問題