我的工作涉及python代码中代码片段的检测。因此,在我的工作中,我将在python中编写一个脚本,以便我将另一个python文件作为输入,并使用我的脚本在所需位置插入任何必要的代码。
以下代码是我将要检测的文件的示例代码:
A.py #normal un-instrumented code
statements
....
....
def move(self,a):
statements
......
print "My function is defined"
......
statements
......
我的脚本实际做的是检查A.py中的每一行,如果有“def”,那么代码片段会在代码顶部检测def函数
以下示例是最终输出应该如何:
A.py #instrumented code
statements
....
....
@decorator #<------ inserted code
def move(self,a):
statements
......
print "My function is defined"
......
statements
......
但是我得到了不同的输出结果。以下代码是我得到的最终输出:
A.py #instrumented code
statements
....
....
@decorator #<------ inserted code
def move(self,a):
statements
......
@decorator #<------ inserted code [this should not occur]
print "My function is defined"
......
statements
......
我可以理解,在经过检测的代码中,它在“已定义”一词中识别出“def”,因此它会对其上方的代码进行检测。
在现实中,检测代码有很多这些问题,我无法正确地检测给定的python文件。有没有其他方法可以区分实际的“def”和字符串?
谢谢
答案 0 :(得分: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
答案 1 :(得分: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
无法想到,如果我们不小心,我们最终会重新编写Python解析器。 @Janne Karila建议使用ast.parse
从长远来看可能更安全。