如何中止 AST 访问者并保持原始节点不变?
How can I abort an AST visitor and leave the original node unchanged?
使用 ast
和 astor
库,我编写了一个简单的脚本,它使用 ast.NodeTransformer
遍历 AST 并将所有空列表替换为 None
:
import ast
import astor
class ListChanger(ast.NodeTransformer):
def visit_List(self, node):
if len(node.elts) > 0:
return ast.copy_location(node, node)
return ast.copy_location(ast.NameConstant(value=None), node)
x = ast.parse("""["A"]""")
ListChanger().visit(x)
print(astor.to_source(x))
y = ast.parse("""[]""")
ListChanger().visit(y)
print(astor.to_source(y))
这可以正常工作,并输出:
["A"]
None
但是,如果列表为空,我不确定用于从函数中提取的行:
return ast.copy_location(node, none)
如果我用return
替换这个,使脚本return None
如果条件不满足,节点被销毁而不是保持不变,进行第一次测试case 打印一个空白字符串,因为 ast.List
节点已被破坏。
我不希望这种情况发生,但我也认为使用 ast.copy_location(node, node)
似乎是错误的。是否有专门的函数来保持节点不变并退出函数,或者配置 ast.NodeTransformer
的方法,以便如果 visit
函数 returns None
,节点保持不变?
The return value may be the original node in which case no replacement takes place.
所以代替:
return ast.copy_location(node, none)
只是:
return node
使用 ast
和 astor
库,我编写了一个简单的脚本,它使用 ast.NodeTransformer
遍历 AST 并将所有空列表替换为 None
:
import ast
import astor
class ListChanger(ast.NodeTransformer):
def visit_List(self, node):
if len(node.elts) > 0:
return ast.copy_location(node, node)
return ast.copy_location(ast.NameConstant(value=None), node)
x = ast.parse("""["A"]""")
ListChanger().visit(x)
print(astor.to_source(x))
y = ast.parse("""[]""")
ListChanger().visit(y)
print(astor.to_source(y))
这可以正常工作,并输出:
["A"]
None
但是,如果列表为空,我不确定用于从函数中提取的行:
return ast.copy_location(node, none)
如果我用return
替换这个,使脚本return None
如果条件不满足,节点被销毁而不是保持不变,进行第一次测试case 打印一个空白字符串,因为 ast.List
节点已被破坏。
我不希望这种情况发生,但我也认为使用 ast.copy_location(node, node)
似乎是错误的。是否有专门的函数来保持节点不变并退出函数,或者配置 ast.NodeTransformer
的方法,以便如果 visit
函数 returns None
,节点保持不变?
The return value may be the original node in which case no replacement takes place.
所以代替:
return ast.copy_location(node, none)
只是:
return node