Python中用ast.NodeVisitor替换除法表达式为div调用遇三角函数问题
解决AST替换除法为div函数的问题
不需要单独添加visit_tan或visit_radians方法,因为在Python AST中,tan()、radians()这类函数调用都统一被解析为ast.Call节点,而非单独的节点类型。
你的代码失效的核心原因是没有正确遍历函数调用内部的参数表达式。默认的ast.NodeVisitor会跳过未实现对应visit方法的节点的子节点,如果你只实现了处理二元运算(visit_BinOp)的逻辑,但未处理Call节点,那么Call节点参数里的除法操作就不会被遍历到,自然无法完成替换。
解决步骤
- 实现
visit_Call方法,在方法内部通过generic_visit递归遍历函数的所有参数(node.args)和关键字参数(node.keywords),确保参数内的表达式被处理。 - 处理完参数后,返回修改后的
Call节点。
示例实现
import ast class DivReplacer(ast.NodeVisitor): def visit_BinOp(self, node): # 先递归处理左右子节点,确保嵌套表达式被处理 self.generic_visit(node) # 替换除法操作符为div函数调用 if isinstance(node.op, ast.Div): return ast.Call( func=ast.Name(id='div', ctx=ast.Load()), args=[node.left, node.right], keywords=[] ) return node def visit_Call(self, node): # 递归处理函数的所有参数,触发内部表达式的替换逻辑 self.generic_visit(node) return node # 测试示例 code = "tan(radians(top / 2)) + (n/7-7)" tree = ast.parse(code, mode='eval') replacer = DivReplacer() new_tree = replacer.visit(tree) print(ast.unparse(new_tree)) # 输出:tan(radians(div(top, 2))) + (div(n, 7) - 7)
这里的generic_visit是关键,它会自动遍历节点的所有子元素,无需为每个函数名单独编写visit方法,不管是tan、radians还是其他自定义函数,都能统一处理内部参数里的除法操作。
内容的提问来源于stack exchange,提问作者user2695082
相关产品推荐
相关产品推荐

