我正在阅读一个代码配方,它使用装饰器使用ast
模块将代码添加到函数体。具体来说,添加的代码会将一些全局变量降低到本地范围。然后将ast对象编译为创建一个附加到函数__code__
属性的代码对象。装饰器代码如下:
def lower_names(*namelist):
def lower(func):
srclines = inspect.getsource(func).splitlines()
for n, line in enumerate(srclines):
if '@lower_names' in line:
break
src = '\n'.join(srclines[n+1:])
top = ast.parse(src, mode='exec')
c1 = NameLower(namelist) # an ast.NodeVisitor subclass that has a
# method to transform the ast node
c1.visit(top)
temp = {}
exec(compile(top, '', 'exec'), temp, temp)
func.__code__ = temp[func.__name__].__code__
return func
return lower
我的问题是为什么要使用ast?为什么不简单地用代码修改函数源来降低全局变量并直接编译它(而不是创建一个ast对象),并将代码对象附加到函数中?使用ast是否有任何优势(如速度)?
答案 0 :(得分:0)
使用ast的一个可能原因可能是直接修改函数所需的工作量。在添加的代码之前需要插入正确数量的空格或制表符以匹配函数体的缩进级别。因此,最好是创建和修改ast。