将python对象转换为python ASTnodes

2024-06-16 12:53:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要将修改过的python对象转储回源代码中。所以我试图找到一些东西来把真正的python对象转换成pythonast.节点(稍后在^{}lib中使用以转储源)

我想要的用法示例,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)

请帮我找到some_magic


Tags: 对象import示例用法节点源代码libmagic
1条回答
网友
1楼 · 发布于 2024-06-16 12:53:48

没有办法做你想做的,因为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

但是getsource()的名字很贴切。 如果我更改m中某个变量(或任何其他对象)的值,它不会更改其源代码。在

即使可以从对象中重新生成AST,也不会有一个解决方案some_magic()可以返回。 假设我在某个模块中有一个变量x,我在另一个模块中重新分配了它:

^{pr2}$

现在,m.x的值是228,但是没有办法知道是什么表达式导致了这个值(好吧,不读取__main__.py的AST,但这很快就会失控)。只是字面意思吗?函数调用的结果?在

如果您确实需要在修改模块的某个值之后获得一个新的AST,那么最好的解决方案是自己转换原始AST。 您可以找到标识符的值的来源,并用您想要的替换赋值的值。 例如,在我的小示例中,x = 0由以下AST表示:

Assign(targets=[Name(id='x', ctx=Store())], value=Num(n=0))

为了得到与我在__main__.py中重新分配匹配的AST,我必须将上面的Assign节点的值更改如下:

value=BinOp(left=Num(n=1), op=Add(), right=Num(n=227))

如果您想这样做,我建议您查看Python关于AST节点转换器(ast.NodeTransformer)的文档,以及这本优秀的手册,其中记录了在Python ASTGreen Tree Snakes - the missing Python AST docs中可以遇到的所有节点。在

相关问题 更多 >