【发布时间】:2011-10-27 00:50:55
【问题描述】:
我一直在 python 中试验 AST。我想通过在运行时转换 AST 来修改方法。
我可以使用inspect.getsource() 获取预编译方法的源代码,并且
我可以使用 AST 访问者根据需要修改 AST。
这可能很幼稚,但我希望能够编译 AST 并做类似的事情:
myClass.method.__func__.__code__ = compile(newAST, '<string>', 'exec')
但是 compile 将只接受带有 ast.Module 作为根的 AST。 有没有办法只编译一个 ast.FunctionDef,或者从已编译的(否则为空的)模块代码中检索函数代码对象?
任何指向此类信息的指针将不胜感激。我见过的 AST 示例只是处理简单的表达式。
我意识到我只需要在命名空间中执行模块,然后我就可以访问正常的结构。 所以模式是:
src = inspect.getsource(myClass.myMethod)
astFromSrc = ast.parse(unindent(src)) # need to remove extra indent from method
transform(astFromSrc.body) # transform the AST as you need
ast.fix_missing_locations(astFromSrc) # fix up line numbers etc
compiled = compile(astFromSrc, '<string>', 'exec') # compile the module AST
####### From here is the part I was missing
myScope = {} # make an empty namespace
exec compiled in myScope # now myScope contains a proper compiled function
# Now replace the original with the modified version
myClass.myMethod.__func__.__code__ = myScope['myMethod'].__code__
但现在我还有一个问题: 如何将其插入到正常的 python 构建过程中,以便只完成一次修改,然后从 .pyc 文件中加载?
【问题讨论】:
-
既然您发现了问题的答案,请将其作为答案发布并接受。
-
@pwray - 这是什么
exec compiled in myScope语法?
标签: python methods abstract-syntax-tree