Python Ast介绍及应用

 Abstract Syntax Trees即抽象语法树。Ast是python源码到字节码的一种中间产物,借助ast模块可以从语法树的角度分析源码结构。此外,我们不仅可以修改和执行语法树,还可以将Source生成的语法树unparse成python源码。因此ast给python源码检查、语法分析、修改代码以及代码调试等留下了足够的发挥空间。

1. AST简介 

Python官方提供的CPython解释器对python源码的处理过程如下:

  1. Parse source code into a parse tree (Parser/pgen.c)
  2. Transform parse tree into an Abstract Syntax Tree (Python/ast.c)
  3. Transform AST into a Control Flow Graph (Python/compile.c)
  4. Emit bytecode based on the Control Flow Graph (Python/compile.c)

即实际python代码的处理过程如下:

源代码解析 --> 语法树 --> 抽象语法树(AST) --> 控制流程图 --> 字节码

上述过程在python2.5之后被应用。python源码首先被解析成语法树,随后又转换成抽象语法树。在抽象语法树中我们可以看到源码文件中的python的语法结构。

大部分时间编程可能都不需要用到抽象语法树,但是在特定的条件和需求的情况下,AST又有其特殊的方便性。

下面是一个抽象语法的简单实例。

复制代码
Module(body=[     Print(           dest=None,           values=[BinOp( left=Num(n=1),op=Add(),right=Num(n=2))],           nl=True,  )])                                
复制代码

2. 创建AST

2.1 Compile函数

先简单了解一下compile函数。

compile(source, filename, mode[, flags[, dont_inherit]]) 

  • source -- 字符串或者AST(Abstract Syntax Trees)对象。一般可将整个py文件内容file.read()传入。
  • filename -- 代码文件名称,如果不是从文件读取代码则传递一些可辨认的值。
  • mode -- 指定编译代码的种类。可以指定为 exec, eval, single。
  • flags -- 变量作用域,局部命名空间,如果被提供,可以是任何映射对象。
  • flags和dont_inherit是用来控制编译源码时的标志。
复制代码
func_def = \ """ def add(x, y):     return x + y print add(3, 5) """
复制代码

使用Compile编译并执行:

复制代码
>>> cm = compile(func_def, '<string>', 'exec') >>> exec cm
>>> 8
复制代码

上面func_def经过compile编译得到字节码,cm即code对象,True == isinstance(cm, types.CodeType)。

compile(source, filename, mode, ast.PyCF_ONLY_AST)  <==> ast.parse(sourcefilename='<unknown>'mode='exec')

2.2 生成ast

使用上面的func_def生成ast.

复制代码
r_node = ast.parse(func_def) print astunparse.dump(r_node)    # print ast.dump(r_node)
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信