Python ast入门

ast

ast全称Abstract Synatx Tree,抽象语法树。常用于对代码的解析与更改,可以用来做ide的python lint功能,或者其他天马行空的功能。

基础概念

示例

1
2
3
4
5
6
import ast

if __name__ == '__main__':
with open('E:/Research/python/ast_test/test.py', 'r') as code_file:
tree = ast.parse(code_file.read())
pass
1
2
3
4
5
6
7
8
9
10
# test.py
globalField1 = 'global'

class Clazz:
field1 = 1

def Func1(self, arg1):
local1 = 'a'
list1 = [1, 2]
return local1

在debug情况下可以看到tree如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
{
tree: {
_attributes: 0,
_fields: {
0: 'body',
__len__: 1,
},
body: [
{ // _ast.Assign object 赋值对象
_attributes: ('lineno', 'col_offset'),
_fields: ('targets', 'value'), // 定义一个属性,有两个部分,左值和右值
col_offset: 0,
lineno: 0,
targets: [ // 这部分代表左侧的globalFields变量
{
_attributes: ('lineno', 'col_offset'),
_fields: ('targets', 'value'),
col_offset: 0,
id: 'globalField1'
lineno: 1
}
__len__: 1
],
value: { // _ast.Str object
_attributes: ('lineno', 'col_offset'),
_fields: ('s',),
col_offset: 15,
lineno: 1,
s: 'global',
}
},
{ // _ast.ClassDef object
_attributes: ('lineno', 'col_offset'),
_fields: ('name', 'bases', 'body', 'decorator_list'),
bases: [], // 没有基类
col_offset: 0,
lineno: 3,
decorator_list: [],
name: 'Clazz',
body: [
{
// Assign object
},
{
_attributes: ('lineno', 'col_offset'),
_fields: ('name', 'args', 'body', 'decorator_list'),
args:{ // arguments object
_fields: ('args', 'vararg', 'kwarg', 'defaults'),
args:[
{}, // self
{
// args变量
// 忽略attribute
_fields: ('id', 'ctx'),
id: 'args1',
ctx: { //Param object
_attributes: (),
_fields: ()
}
},
],
defaults: [
{ // Str object
s: 'default'
}
]
},
body: {
// 忽略两个Assign
{},
{},
{ // Return object
_fields: ('value')
value: { // Name object
_fields: ('id', 'ctx')
id: 'local1',
ctx: {} // Load object
}
}
}
}
],
}
__len__ = 2
],
}
}

可以看到每个object都有的几个属性:

  • _attributes 属性 一般就两个,一个lineno代表在哪一行,一个col_offset表示在第几列
  • _field 域 类型tuple,这个根据不同类型有不同的field。比如对于一个字符串来说,他有特殊的域s,代表着字符串内容。对于一个类来说,有name名字、bases基类、body正文、decorator_list装饰器几个域。

Str

字符串对象只有一个域s,代表字符串内容

Num

一个域n,代表数字。

赋值对象

赋值对象有两个域值得关注,一个是左值targets(为什么是复数呢,因为左值可以是多个),右值value。

target其实是一个Name对象,有一个id代表名字,一个ctx不知为何。

value的类型不定,为右值的类型。譬如当为数字的时候,为_ast.Num类型;为字符串的时候,为_ast.Str类型。

函数对象

1
2
3
4
def Func1(self, arg1='default'):
local1 = 'a'
list1 = [1, 2]
return local1

几个值得注意的域:

  • name 函数名
  • args 参数 类型为arguments。arguments对象有有几个域,一个为args,一个代表参数的列表;另一个为defaults,代表默认值
  • body 具体的函数内容
  • drcorator_list 装饰器

函数体body是一个列表,里面每个元素都代表一个可执行语句。上文中有两个赋值语句,以及最后的一个返回语句。返回语句为Return对象,Return只有一个域value,此value的类型可能为常量,也可能为变量。为常量时类型为常量具体的类型如Num、Str等等,为变量时为Name类型,id为欲返回的变量之名。

列表对象

1
list1 = [1, 2]

重要的域有一个为elts,类型是一个list,里面是数组的内容。

字典对象

1
list1 = {'target': 'value', 'target1': 'value1'}

域中,keys列表代表键,values列表代表值 废话

类对象

类对象域:

  • bases 表示基类,元素的类型仍然是Name
  • body 类体
  • decorator_list 装饰器
  • name 类名

应用

待填坑。

Buy Me A Coffee / 捐一杯咖啡的钱
分享这篇文章~
0%
//