将python对象转换为python AST节点 [英] Convert python objects to python AST-nodes

查看:148
本文介绍了将python对象转换为python AST节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将修改后的python对象转储回源代码。因此,我尝试找到将真正的python对象转换为python ast.Node的方法(稍后在 astor lib转储源代码)

I have a need to dump the modified python object back into source. So I try to find something to convert real python object to python ast.Node (to use later in astor lib to dump source)

我想要的用法示例,Python 2:

Example of usage I want, 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

推荐答案

无法执行您想要的操作,因为这不是AST的工作方式。
当解释器运行您的代码时,它将从源文件中生成一个AST,并解释该AST以生成python对象。
这些对象一旦生成就会发生什么事与AST无关。

There's no way to do what you want, because that's not how ASTs work. When the interpreter runs your code, it will generate an AST out of the source files, and interpret that AST to generate python objects. What happen to those objects once they've been generated has nothing to do with the AST.

但是可以获取生成对象的AST。对象放在首位。
模块检查可让您获取某些python对象的源代码:

It is however possible to get the AST of what generated the object in the first place. The module inspect lets you get the source code of some python objects:

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 中某个变量(或任何其他对象)的值,它将不会更改其源代码。

But getsource() is aptly named. If I were to change the value of some variable (or any other object) in m, it wouldn't change its source code.

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

Even if it was possible to regenerate an AST out of an object, there wouldn't be a single solution some_magic() could return. Imagine I have a variable x in some module, that I reassign in another module:

# In some_module.py
x = 0

# In __main__.py
m = importlib.import_module('some_module')
m.x = 1 + 227

现在, mx 228 ,但是无法知道导致该值的表达式是什么(嗯,如果没有阅读 __ main __。py ,但这很快就会失去控制)。这仅仅是文字吗?函数调用的结果?

Now, the value of m.x is 228, but there's no way to know what kind of expression led to that value (well, without reading the AST of __main__.py but this would quickly get out of hand). Was it a mere literal? The result of a function call?

如果修改模块的某些值后确实必须获得新的AST,最好的解决方案是通过以下方法转换原始AST:你自己
您可以找到标识符的值所在的位置,然后将分配的值替换为所需的值。
例如,在我的小示例中, x = 0 由以下AST表示:

If you really have to get a new AST after modifying some value of a module, the best solution would be to transform the original AST by yourself. You can find where your identifier got its value, and replace the value of the assignment with whatever you want. For instance, in my small example x = 0 is represented by the following AST:

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

要获得与我在 __ main __。py 中所做的重新分配相匹配的AST,我必须进行更改上面的 Assign 节点的值如下:

And to get the AST matching the reassignment I did in __main__.py, I would have to change the value of the above Assign node as the following:

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

如果您想这样做,建议您检查AST节点转换器的Python文档( ast.NodeTransformer ),以及这份出色的手册,其中记录了您可以在Python AST中遇到的所有节点绿树蛇-缺少的Python AST文档

If you'd like to go that way, I recommend you check Python's documentation of the AST node transformer (ast.NodeTransformer), as well as this excellent manual that documents all the nodes you can meet in Python ASTs Green Tree Snakes - the missing Python AST docs.

这篇关于将python对象转换为python AST节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆