【问题标题】:Compile python AST to method将 python AST 编译为方法
【发布时间】: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


【解决方案1】:

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

请注意,您的第一个和第二个问题也有点矛盾。首先你想在运行时做一些事情,然后你想把它们写到一个文件中,这样你就不必一遍又一遍地做。请说明您的最终目标,以便我们清楚地知道您想要什么。

听起来您最好在修改您解析的文件的 ast 后创建一个新的 .py 文件,如 Parse a .py file, read the AST, modify it, then write back the modified source code 中所述

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-16
    • 1970-01-01
    • 1970-01-01
    • 2016-07-15
    • 1970-01-01
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多