Vla*_*mir 3 python code-generation
我需要将修改后的 python 对象转储回源代码。所以我尝试找到一些东西将真正的python对象转换为python ast.Node(稍后在astorlib中使用以转储源代码)
我想要的用法示例,Python 2:
import ast
import importlib
import astor
m = importlib.import_module('something')
# modify an object
m.VAR.append(123)
ast_nodes = some_magic(m)
source = astor.dump(ast_nodes)
Run Code Online (Sandbox Code Playgroud)
请帮我找到那个 some_magic
没有办法做你想做的事,因为这不是 AST 的工作方式。当解释器运行您的代码时,它将从源文件中生成一个 AST,并解释该 AST 以生成 python 对象。这些对象生成后会发生什么与 AST 无关。
然而,可以首先获得生成对象的 AST。该模块inspect可让您获取一些 Python 对象的源代码:
import ast
import importlib
import inspect
m = importlib.import_module('pprint')
s = inspect.getsource(m)
a = ast.parse(s)
print(ast.dump(a))
# Prints the AST of the pprint module
Run Code Online (Sandbox Code Playgroud)
但getsource()名字恰如其分。如果我要更改 中某个变量(或任何其他对象)的值m,它不会更改其源代码。
即使可以从对象中重新生成 AST,也不会some_magic()返回单个解决方案。想象一下,我x在某个模块中有一个变量,我在另一个模块中重新分配了该变量:
# In some_module.py
x = 0
# In __main__.py
m = importlib.import_module('some_module')
m.x = 1 + 227
Run Code Online (Sandbox Code Playgroud)
现在, 的值为m.xis 228,但无法知道是哪种表达式导致了该值(好吧,不阅读 的 AST__main__.py但这很快就会失控)。仅仅是字面意思吗?函数调用的结果?
如果在修改某个模块的某些值后确实必须获得新的 AST,最好的解决方案是自己转换原始 AST。你可以找到你的标识符从哪里得到它的值,并用你想要的任何值替换分配的值。例如,在我的小例子x = 0中由以下 AST 表示:
Assign(targets=[Name(id='x', ctx=Store())], value=Num(n=0))
Run Code Online (Sandbox Code Playgroud)
为了使 AST 与我在 中所做的重新分配相匹配__main__.py,我必须将上述Assign节点的值更改为如下所示:
value=BinOp(left=Num(n=1), op=Add(), right=Num(n=227))
Run Code Online (Sandbox Code Playgroud)
如果您想这样做,我建议您查看 Python 的 AST 节点转换器 ( ast.NodeTransformer ) 文档,以及这本出色的手册,其中记录了您可以在 Python AST 中遇到的所有节点Green Tree Snakes - the missing Python AST 文档。
| 归档时间: |
|
| 查看次数: |
1567 次 |
| 最近记录: |