我一直在python中试验AST。我想通过在运行时转换AST来修改方法。
我可以使用inspect.getsource()
来获取预编译方法的来源
我可以根据需要使用AST访问者修改AST。
这可能很天真,但我希望能够编译AST并做类似的事情:
myClass.method.__func__.__code__ = compile(newAST, '<string>', 'exec')
但是编译只接受带有作为root的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文件加载?
答案 0 :(得分:1)
您不应该在自己的答案中提出新问题,而是为此创建一个单独的问题。
请注意,您的第一个和第二个问题也有点矛盾。首先,您希望在运行时执行操作,之后您希望将它们写入文件,这样您就不必一遍又一遍地执行此操作。请说明您的结果,以便我们清楚地知道您的需求。
听起来你可能在修改你解析的文件的ast之后创建一个新的.py文件,如Parse a .py file, read the AST, modify it, then write back the modified source code中所述
然后,您将通过编译新创建的py文件来获取您的pyc文件。