【问题标题】:Convert python objects to python AST-nodes将 python 对象转换为 python AST 节点
【发布时间】:2017-09-20 08:50:13
【问题描述】:

我需要将修改后的 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)

请帮我找到some_magic

【问题讨论】:

  • 为什么?这似乎是您描述您想要的解决方案而不是问题本身的情况。如果我不得不冒险猜测,那么您正在尝试在下次代码运行时保持对象的状态。这是将对象序列化为 JSON 格式并将它们保存到文件中的完美情况!!然后当代码再次运行时,您只需从文件中反序列化即可。
  • 好吧,可以。问题 - 我想通过生成模板模型、表单、模板、视图、url 来加速开发简单的 django 页面。问题在于修改 django url。这是一个列表。所以我不能只写在文件的末尾。
  • 使用pickle、JSON等序列化格式
  • @Aaron3468,谢谢,但我们需要将其转换回源代码。这是给人类的。示例 - 生成新的 django 模型和 url

标签: python code-generation


【解决方案1】:

没有办法做你想做的事,因为这不是 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,我在另一个模块中重新分配了它:

# In some_module.py
x = 0

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

现在,m.x 的值是 228,但无法知道是哪种表达式导致了该值(好吧,如果不阅读 __main__.py 的 AST,但这很快就会失控) .它只是字面意思吗?函数调用的结果?

如果你真的需要在修改某个模块的某个值后得到一个新的 AST,最好的解决方案是自己改造原来的 AST。 你可以找到你的标识符从哪里得到它的值,并用你想要的任何东西替换赋值的值。 例如,在我的小示例中,x = 0 由以下 AST 表示:

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

为了使 AST 与我在 __main__.py 中所做的重新分配相匹配,我必须将上述 Assign 节点的值更改如下:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    • 2018-12-28
    • 2019-03-17
    • 1970-01-01
    • 2022-01-07
    • 2019-04-02
    • 1970-01-01
    相关资源
    最近更新 更多