Python通过AST动态重载赋值运算符时astunparse报错问题
报错原因
你的AST节点构造不符合Python官方的AST规范:ast.Expr的value属性只支持接收单个表达式节点,你错误地将ast.Call节点包裹在列表中传入了ast.Expr,astunparse的Unparser遍历到这个非法结构时无法识别处理,因此抛出AttributeError: 'Unparser' object has no attribute '_str'错误。你输出的AST结构中Expr(value=[Call(...)])也能印证这个问题,合法结构应为Expr(value=Call(...))。
另外你代码中还存在一处语法笔误:Python的逻辑与运算符是and,不是你写的&&,运行时会直接触发语法错误。
修复方案
调整visit_Assign方法中返回节点的构造逻辑,修复后的完整代码如下:
import ast import astunparse class OverloadAssignments(ast.NodeTransformer): def visit_Assign(self, node): if isinstance(node, ast.Assign) and node.targets: funcs = node.targets[0] slot_name_candidate = astunparse.unparse(funcs).strip() if isinstance(funcs, ast.Name) and "_slot" in slot_name_candidate: slot_name = ast.Constant(value=slot_name_candidate) context_variable = ast.Constant(value=astunparse.unparse(node.value).strip()) # 去掉外层列表,直接将Call节点传给Expr的value参数 return ast.Expr( value=ast.Call( func=ast.Name(id='copy_variable_value', ctx=ast.Load), args=[slot_name, context_variable], keywords=[] ) ) else: return node return node assignment_overloader = OverloadAssignments() code_chunk = "town_slot=cxt.my_town" tree = ast.parse(code_chunk) tree = assignment_overloader.visit(tree) # 修复后可正常反解析 print(astunparse.unparse(tree).strip())
运行上述代码即可得到你预期的输出copy_variable_value("town_slot", "cxt.my_town")。
内容的提问来源于stack exchange,提问作者Alexander Borochkin
相关产品推荐
相关产品推荐

