2011-08-15 54 views
9

我一直在用python试验ASTs。我想通过在运行时转换AST来修改方法。编译python AST到方法

我可以通过使用inspect.getsource()和 来获得预编译方法的来源我可以根据AST访问者的要求修改AST。

这可能是相当幼稚,但我希望能够编译AST和做一个类似于:

myClass.method.__func__.__code__ = compile(newAST, '<string>', 'exec') 

但是编译只接受与ast.Module作为root 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__ 

但现在我还有一个问题: ,以便修改一次时进行,之后从.pyc文件文件加载如何插槽进入正常的Python构建过程呢?

+2

既然您发现了您的问题的答案,请将其作为答案发布并接受。 – cpburnz

回答

1

你不应该在你自己的答案中提出一个新问题,而是为此创建一个单独的问题。

请注意,你的第一个和第二个问题也有矛盾。首先,您希望在运行时执行某些操作,之后您希望将它们写入文件,以便不必一遍又一遍地执行操作。请说明你的目标是如此我们清楚地知道你想要什么。

这听起来像你可能只是以及修改您剖析为Parse a .py file, read the AST, modify it, then write back the modified source code

解释,那么你将通过编译新创建的PY获得您的PYC文件的文件的AST之后创建一个新的.py文件文件。