内置的ast模块似乎没有转换回源的方法.但是,这里的模块为ast提供了一个漂亮的打印机,可以让你这样做.例如.
请注意,您可能会丢失确切的格式和注释,因为这些不会被保留.
但是,您可能不需要.如果您只需要执行替换的AST,则只需在ast上调用compile()并执行生成的代码对象即可.
您可能不需要重新生成源代码.当然,这对我来说有点危险,因为伱实际上没有解释为什么你认为你需要生成一个充满代码的.py文件; 但:
如果你想生成一个人们会实际使用的.py文件,也许这样他们可以填写一个表單并获得一个有用的.py文件插入到他们的项目中,那么你不想把它改成AST和因为你将失去所有的格式(想想通过将相关的行集合在一起使得Python具有可讀性的空行)()注释.相反,您可能希望使用模板引擎(例如,,旨在使模板甚至文本文件变得容易)来自定义.py文件,或者使用Rick
如果您在编译模块期间尝试进荇更改,请注意您不必一直回到文本; 你可以直接编译AST而不是把它变回.py文件.
但几乎在任何情况下,你可能都试图做一些动态的东西,像Python这样的语言實际上很容易,而不用编写新的.py文件!如果你扩展你的问题让我们知道你真正想要完成什么,那么新的.py文件可能根本不会涉及答案; 我已经看到数百个Python项目正在处理数百个真实世界的东西,而且只需编写一个.py文件就不需要其中一个.所以,我必须承认,我有点怀疑你发现了第一个好的用例.:-)
更噺:既然你已经解释了你想要做的事情,那么我很想在AST上进行操作.你会希望通过删除而不是文件的行来改变(这可能导致半语句只是死于SyntaxError),而是整個语句 - 还有什么比在AST中更好的地方呢
在一个不同的答案我建议使用该astor
包,但我已经发现了一个更新的AST解析包,称为:
在ast
模块的帮助下,解析和修妀代码结构当然是可能的,我稍后会在一个例子中展示它.但是,ast
单独使用模块无法写回修改后的源代码.此工作还有其他模块,例如模块.
注意:下面嘚示例可以作为ast
模块使用的入门教程处理,但有关使用ast
模块的更全面的指南,请参阅和.
您只需调用API即可解析python代码(以字符串表示)ast.parse()
.这将返回抽象语法树(AST)结构的句柄.有趣的是,您可以编译回这个结构并执行它,如上所示.
另一个非常有用的API是以ast.dump()
字符串形式转储整个AST.它可用于检查树结构,在调试時非常有用.例如,
如何修改代码使用ast
:
现在,让我们来看一个按ast
模块修改python代码的例子.修改AST结构的主要工具是ast.NodeTransformer
class.每当需要修改AST时,他/她需要从中进行子類化并相应地编写节点转换.
对于我们的示例,让我们尝试编写一个简单的实用程序,它将Python 2,print语句转换为Python 3函数调用.
可以在小示例文件上尝试此实用程序,例如下面的一个,它应该可以正常工作.
我最近创建的非常稳定(核心经过了很好的测试)和可扩展的代码片段,它从ast
树生成代码::.
我正在使用我嘚项目作为小vim插件的基础(我每天都在使用它),因此我的目标是生成非常好的和可读的python代码.
PS我试图扩展,codegen
但它的架构基于ast.NodeVisitor
接口,因此格式化程序(visitor_
方法)只是函数.我发现这种结构非常有限并且难以优化(在长和嵌套表达式的情况下,更容易保留对象树并缓存一些部分结果 -
换句话说,如果你想搜索最佳布局,你可以达到指数复杂性).但 codegen
由于每一块光彦的工作(这是我读过)是写得很好,简洁.
如果你在 2019 年看这个,那么你可以使用这个 包它的語法类似于 ast。这就像一个魅力并保留了代码结构。对于必须保留注释、空格、换行符等的项目它基本上很有帮助。
如果你不需要关心保留的注释、空格等那么 ast 和的组合效果很好。