将Python AST编译为方法

10

我一直在尝试使用 Python 中的 AST。我想通过在运行时转换AST来修改方法。

使用 inspect.getsource(),我可以获取预编译方法的源代码,并且可以通过使用AST访问器根据需要修改AST。

这可能相当幼稚,但我希望能够编译AST并执行类似以下操作的内容:

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

但是,编译器只会接受以ast.Module为根的AST。是否有一种方法可以仅编译ast.FunctionDef,或者从已编译的(并且其他部分为空)Module代码中检索函数代码对象?

如果有任何涵盖此类内容的信息指针,将不胜感激。我看到的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文件中加载?


3
既然你已经找到了问题的答案,就将它发布为一个回答并接受它。 - Uyghur Lives Matter
@pwray - 这个 exec compiled in myScope 语法是什么意思? - Samuel Marks
1个回答

1

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

请注意,你的第一个和第二个问题似乎有些矛盾。首先,你想在运行时完成一些操作,然后你又想将它们写入文件,这样你就不必一遍又一遍地做了。请明确说明你的最终目标,以便我们清楚地知道你想要什么。

看起来你最好是在解析文件的ast后修改它,然后创建一个新的.py文件,如解析.py文件,读取AST,修改它,然后写回修改后的源代码所述。

然后通过编译新创建的py文件来获得你的pyc文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接