pwr*_*ray 10 python methods abstract-syntax-tree
我一直在python中试验AST.我想通过在运行时转换AST来修改方法.
我可以使用预编译方法的源代码inspect.getsource(),并且可以根据需要使用AST访问者修改AST.
这可能很天真,但我希望能够编译AST并做类似的事情:
myClass.method.__func__.__code__ = compile(newAST, '<string>', 'exec')
Run Code Online (Sandbox Code Playgroud)
但是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__
Run Code Online (Sandbox Code Playgroud)
但现在我有另一个问题:如何将其插入到正常的python构建过程中,以便修改只进行一次,然后从.pyc文件加载?
您不应在自己的答案中提出新问题,而应为此创建一个单独的问题。
请注意,您的第一个问题和第二个问题也有点矛盾。首先,您想在运行时执行操作,然后您想将它们写入文件,这样您就不必一遍又一遍地执行此操作。请说明您的最终目标,以便我们清楚地知道您想要什么。
听起来您不妨在修改您解析的文件的 ast 之后创建一个新的 .py 文件,如解析 .py 文件中所述,读取 AST,修改它,然后写回修改后的源代码
然后,您将通过编译新创建的 py 文件来获取 pyc 文件。