[TOC] <br/><br/><br/> # <b style="color:#4F4F4F;">简介说明</b> 原文链接: - [ast](https://docs.python.org/zh-cn/3.9/library/ast.html#module-ast) ``` 版本:ast 作用:抽象语法树 ``` <br/> # <b style="color:#4F4F4F;">ast</b> <br/> # <span style="color:#619BE4">*parse()</span> ***** 解析字符串成为model对象,与compile()函数一样 <br/> ### 返回类型 ``` ast.Module ``` <br/> ### 示例内容 <span style="color:red;">1. 解析成AST对象</span> ``` expr = """ def add(arg1, arg2): return arg1 + arg2 """ expr_ast = ast.parse(expr) ``` <br/> # <span style="color:#619BE4">*unparse()</span> ***** 反解析ast树对象生成python代码 <br/> # <span style="color:#619BE4">*dump()</span> ***** 返回ast树字符串格式 <br/> # <span style="color:#619BE4">*literal_eval()</span> ***** 对表达式节点以及包含Python字面量或容器的字符串进行安全的求值 <br/> # <span style="color:#619BE4">*get_docstring()</span> ***** 返回给定节点的文档字符 <br/> # <span style="color:#619BE4">*get_source_segment()</span> ***** 获取生成节点的源代码的源代码段 <br/> # <span style="color:#619BE4">*increment_lineno()</span> ***** 从节点开始,将树中每个节点的行号和结束行号递增n <br/> # <span style="color:#619BE4">*copy_location()</span> ***** 如果可能,将源位置(lineno,col_offset,end_lineno和end_col_offset)从old_node复制到new_node,然后返回new_node <br/> # <span style="color:#619BE4">*iter_fields()</span> ***** 迭代字段 <br/> # <span style="color:#619BE4">*iter_child_nodes()</span> ***** 迭代子节点 <br/> # <span style="color:#619BE4">*walk()</span> ***** 遍历节点 <br/> # <span style="color:#619BE4">*fix_missing_locations()</span> ***** 在当前作用域下修复的ast语法树 <br/> ### 示例内容 <span style="color:red;">1. 举例说明</span> ``` import ast expr = """ def add(arg1, arg2): return arg1 + arg2 """ expr_ast = ast.parse(expr) class CrazyTransformer(ast.NodeTransformer): def visit_BinOp(self, node): node.op = ast.Mult() return node transformer = CrazyTransformer() ast.fix_missing_locations(transformer.visit(expr_ast)) a = compile(expr_ast, "<string>", mode="exec") exec(a) print(add(8, 2)) ``` <br/> # <span style="color:#619BE4">*[new]-Module()</span> ***** 节点,模块节点 <br/> # <span style="color:#619BE4">*[new]-Constant()</span> ***** 节点,常量节点 <br/> # <span style="color:#619BE4">*[new]-FormattedValue()</span> ***** 节点,FormattedValue <br/> # <span style="color:#619BE4">*[new]-JoinedStr()</span> ***** 节点,JoinedStr <br/> # <span style="color:#619BE4">*[new]-List()</span> ***** 节点,List <br/> # <span style="color:#619BE4">*[new]-Tuple()</span> ***** 节点,Tuple <br/> # <span style="color:#619BE4">*[new]-Set()</span> ***** 节点,Set <br/> # <span style="color:#619BE4">*[new]-Dict()</span> ***** 节点,Dict <br/> # <b style="color:#4F4F4F;">ast.AST</b> <br/> # <span style="color:#619BE4">[new]-AST()</span> ***** 抽象语法树基类 <br/> # <span style="color:#619BE4">_fields</span> ***** 所有子节点的名字 <br/> # <span style="color:#619BE4">lineno</span> ***** 行号 <br/> # <span style="color:#619BE4">end_lineno</span> ***** 结束行号 <br/> # <span style="color:#619BE4">col_offset</span> ***** 列偏移 <br/> # <span style="color:#619BE4">end_col_offset</span> ***** 列偏移结束位置 <br/> # <b style="color:#4F4F4F;">ast.NodeVisitor</b> <br/> # <span style="color:#619BE4">[new]-NodeVisitor()</span> ***** 抽象语法树遍历类 <br/> # <span style="color:#619BE4">visit()</span> ***** 访问一个节点 <br/> # <span style="color:#619BE4">generic_visit()</span> ***** 此访问者在节点的所有子节点上调用 visit() <br/> # <b style="color:#4F4F4F;">ast.NodeTransformer</b> <br/> # <span style="color:#619BE4">[ext]-NodeVisitor()</span> ***** 抽象语法树遍历类 <br/> # <span style="color:#619BE4">[new]-NodeTransformer()</span> ***** 子类 NodeVisitor 用于遍历抽象语法树,并允许修改节点 <br/> ### 示例内容 <span style="color:red;">1. 举例说明</span> ``` import ast expr = """ def add(arg1, arg2): return arg1 + arg2 """ expr_ast = ast.parse(expr) class CrazyTransformer(ast.NodeTransformer): def visit_BinOp(self, node): node.op = ast.Mult() return node transformer = CrazyTransformer() modified = transformer.visit(expr_ast) pro = compile(modified, '<string>', 'exec') exec(pro) print(add(8,2)) ``` <span style="color:red;">2. 举例说明</span> ``` import ast class CodeTransformer(ast.NodeTransformer): def visit_BinOp(self, node): if isinstance(node.op, ast.Add): node.op = ast.Sub() self.generic_visit(node) return node def visit_FunctionDef(self, node): self.generic_visit(node) # 这里表示先去访问里面的children node if node.name == 'add': node.name = 'sub' args_num = len(node.args.args) args_num = len(node.args.args) args = tuple([arg.arg for arg in node.args.args]) print(str(args)) func_log_stmt = ''.join(["print('calling func: %s', " % node.name, "'args:'", ", %s" * args_num % args, ')']) node.body.insert(0, ast.parse(func_log_stmt)) # func_log_stmt = ''.join(["print 'calling func: %s', " % node.name, "'args:'", ", %s" * args_num % args]) # node.body.insert(0, ast.parse(func_log_stmt)) return node def visit_Name(self, node): replace = {'add': 'sub', 'x': 'a', 'y': 'b'} re_id = replace.get(node.id, None) node.id = re_id or node.id self.generic_visit(node) return node def visit_arg(self, node): self.generic_visit(node) replace = {'x': 'a', 'y': 'b'} node.arg = replace[node.arg] return node func_def = \ """ def add(x, y): return x+y """ r_node = ast.parse(func_def) transformer = CodeTransformer() r_node = transformer.visit(r_node) source = ast.unparse(r_node) print(source) ``` <br/>