使用AST模块来更改和删除分配/函数调用 [英] Use AST module to mutate and delete assignment/function calls
问题描述
例如,如果我想更改大于或小于等于我已成功执行,则
def visit_Gt( self,node):
new_node = ast.GtE()
return ast.copy_location(new_node,node)
我将如何访问/检测赋值操作( =
)和函数调用()
并删除它们?我正在阅读AST文档,但找不到找到访问赋值或函数调用类然后不返回任何内容的方法。
我的示例m寻求分配操作:
print( Start)
x = 5
print( End )
成为:
print(开始)
print(结束)
以及我要删除的函数调用示例:
print( Start)
my_function_call(Args)
print( End)
成为
print(开始)
打印(结束)
您可以使用 ast.NodeTransformer()
子类来更改现有的AST树:
import ast
类RemoveAssignments(ast.NodeTransformer):
def visit_Assign(自身,节点):
返回无
def visit_AugAssign(自身,节点):
返回无
new_tree = RemoveAssignments()。visit(old_tree)
以上类删除无
从输入树中完全删除该节点。 Assign
和 AugAssign
节点包含整个赋值语句,因此产生结果的表达式以及目标列表(1或更多名称来将结果分配给该名称。)
这意味着上面的内容将会变成
print('开始!')
foo ='bar'
foo + ='鸡蛋'
print('完成!')
进入
print('开始!')
打印('完成!')
如果您需要做出更细粒度的决策,请直接查看分配的子节点,或者将子节点传递给 self.visit()
如果存在的话,让变压器进一步调用 visit _ *
挂钩:
class RemoveFunctionCallAssignments(NodeTransformer):
删除形式为 target = name()的分配,因此将单个名称称为
目标列表大小不起作用。
def visit_Assign(自己,节点):
如果isinstance(node.value,ast.Call)和isinstance(node.value.func,ast.Name):
返回None
返回节点
此处,我们仅返回 None
如果赋值的值侧(右侧的表达式)是 Call
节点,该节点应用于简单的 Name
节点。返回传入的原始节点对象意味着它不会被替换。
要替换 toptop-level 函数调用(因此那些没有赋值或其他表达式),请查看 Expr
节点;这些是表达式 statements ,而不仅仅是属于其他某些构造的表达式。如果您有一个 Expr
节点且具有 Call
,则可以将其删除:
def visit_Expr(self,node):
#如果是isinstance(node.value,则将删除对单个名称的独立调用
,ast.Call)和isinstance(node.value.func,ast.Name):
返回None
返回节点
另请参见出色的 绿树蛇文档,其中介绍了在AST树上的工作,并附有更多示例。 p>
For example if I wanted to change greater than to less than or equal to I have successfully executed:
def visit_Gt(self, node):
new_node = ast.GtE()
return ast.copy_location(new_node, node)
How would I visit/detect an assignment operation (=
) and a function call ()
and simply delete them? I'm reading through the AST documentation and I can't find a way to visit the assignment or function call classes and then return nothing.
An example of what I'm seeking for assignment operations:
print("Start")
x = 5
print("End")
Becomes:
print("Start")
print("End")
And an example of what I'm seeking for deleting function calls:
print("Start")
my_function_call(Args)
print("End")
Becomes
print("Start")
print("End")
You can use a ast.NodeTransformer()
subclass to mutate an existing AST tree:
import ast
class RemoveAssignments(ast.NodeTransformer):
def visit_Assign(self, node):
return None
def visit_AugAssign(self, node):
return None
new_tree = RemoveAssignments().visit(old_tree)
The above class removes None
to completely remove the node from the input tree. The Assign
and AugAssign
nodes contain the whole assignment statement, so the expression producing the result, and the target list (1 or more names to assign the result to).
This means that the above will turn
print('Start!')
foo = 'bar'
foo += 'eggs'
print('Done!')
into
print('Start!')
print('Done!')
If you need to make more fine-grained decisions, look at the child nodes of the assignment, either directly, or by passing the child nodes to self.visit()
to have the transformer further call visit_*
hooks for them if they exist:
class RemoveFunctionCallAssignments(NodeTransformer):
"""Remove assignments of the form "target = name()", so a single name being called
The target list size plays no role.
"""
def visit_Assign(self, node):
if isinstance(node.value, ast.Call) and isinstance(node.value.func, ast.Name):
return None
return node
Here, we only return None
if the value side of the assignment (the expression on the right-hand side) is a Call
node that is applied to a straight-forward Name
node. Returning the original node object passed in means that it'll not be replaced.
To replace top-level function calls (so those without an assignment or further expressions), look at Expr
nodes; these are expression statements, not just expressions that are part of some other construct. If you have a Expr
node with a Call
, you can remove it:
def visit_Expr(self, node):
# stand-alone call to a single name is to be removed
if isinstance(node.value, ast.Call) and isinstance(node.value.func, ast.Name):
return None
return node
Also see the excellent Green Tree Snakes documentation, which covers working on the AST tree with further examples.
这篇关于使用AST模块来更改和删除分配/函数调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!