我正在尝试注释来自 Python 源代码的函数调用。
我阅读了字符串中的源代码,然后尝试应用一些正则表达式来注释方法调用。
这是一个简单的示例:
s = open(path, 'r').read()
# comment method calls
result = re.sub('(^[.\w]+\(.*\))', r'#\1', s, flags=re.MULTILINE)
如您所见,我正在源代码的第一个缩进级别中注释函数(__name__ == '__main__'
、方法和类之外的代码)
但是,如何使这个正则表达式能够处理多行调用?
例如,如果我将以下代码放入字符串中:
Builder.load_string('''
type: 'example'
callback: my_callback()
''')
如何评论此调用的每一行?
最佳答案
这将为您提供需要评论的行号:
mod = "test1"
mod = importlib.import_module(mod)
p = ast.parse(inspect.getsource(mod))
for n in p.body:
if isinstance(n, ast.Expr):
for node in ast.walk(n):
if isinstance(node, ast.Call):
print(node.lineno)
对于如下文件:
import math
class Foo:
def __init__(self):
self.foo = 4
def bar(self):
print("hello world")
def foo(self):
return self.bar()
def bar():
return 123
f = Foo()
f.bar()
bar()
它将输出 16
和 18
这两个调用。
这只是忽略这些行并编写新源代码或对更新内容执行任何您想要的操作的问题:
import inspect
import importlib
import ast
def get_call_lines(mod):
mod = importlib.import_module(mod)
p = ast.parse(inspect.getsource(mod))
for n in p.body:
if isinstance(n, ast.Expr):
for node in ast.walk(n):
if isinstance(node, ast.Call):
yield(node.lineno)
from StringIO import StringIO
new = StringIO()
with open("test1.py") as f:
st = set(get_call_lines("test1"))
for ind, line in enumerate(f, 1):
if ind not in st:
new.write(line)
new.seek(0)
print(new.read())
新内容将包含:
import math
class Foo:
def __init__(self):
self.foo = 4
def bar(self):
print("hello world")
def foo(self):
return self.bar()
def bar():
return 123
f = Foo()
您可以使用 ast.NodeTransformer
在运行时更改代码,但删除节点并不是一项简单的任务,您想要的最简单的方法是忽略正文
关于python - 用源代码在字符串中注释Python函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32574948/