Python ast 学习笔记1–手动建ast

Python ast 学习笔记1–手动建ast

手动建ast

python中的ast模块是非常强大的模块,可以用来修改python源码,或者分析python源码。为了学习ast模块,先来手动建立一个ast熟悉熟悉。

将用ast来表示下列代码:

foo = 2
if foo == 2print foo
else:
    print "not equal"

foo=2

foo=2是一个赋值语句,可以分为3个Node。foo是一个变量,=是表示赋值,2是一个常量。

foo是一个变量ast.Name,id为变量的名字,ctx表示该变量的用途,Store即分配。

assign_foo = ast.Name(id='foo',ctx=ast.Store())

这里就得到了变量foo,用于赋值。

2是一个字面常量,可以用以下代码表示。
two = ast.Num(n=2)

赋值=ast.Assign表示,targets为list表示被赋值的点,value为要给变量的值。lineno为行号,col_offset为列号。用过用函数compile()每个Node都需要lineno,可以直接函数fix_missing_locations,该函数会递归的添加lineno。

assign_2 = ast.Assign(targets=[copy(assign_foo)],value=copy(two))
assign_2.lineno = 1
assign_2.col_offset = 0
ast.fix_missing_locations(assign_2)

如果不用copy,完整版可以写为为:

assign_2 = ast.Assign(targets=[
        ast.Name(id='foo',ctx=ast.Store())],
        value=ast.Num(n=2))
assign_2.lineno = 1
assign_2.col_offset = 0
ast.fix_missing_locations(assign_2)

if语句

if语句稍微复杂些。if语句的定义为:
test为测试节点,body是一序列的节点,orelse也是一序列的节点。

class If(test, body, orelse)

if.test

use_foo = ast.Name(id='foo',ctx = ast.Load()) 

if_ = ast.If()
if_.test = ast.Compare() 
if_.test.left = copy(use_foo)
if_.test.ops = [ast.Eq()]
if_.test.comparators = [copy(two)]

上面代码为声明了if foo==2:,Compare的定义为

class Compare(left, ops, comparators)

其中,left为比较符号的左边,这里用foo,ops为操作符号可以为下列中的某个,这里用Eq表示==。comparators为第一个以后要比较的值(例如 1< a < 3中的1和3)。use_foo为使用变量foo,与赋值不同的是ctx为Load。

class Eq, class NotEq, class Lt, class LtE,
class Gt, class GtE, class Is, class IsNot, class In, class NotIn

if.body

if的body此处只有一句话,就是print定义为Print(dest, values, nl),dest为print>>dest,此处我们不需要。values要打印的值,nl为是否换行。

if_.body = [ast.Print(dest=None,values=[copy(use_foo)],nl=True)]

if.orelse

了解上面以后,else部分就比较简单了。其中Str为字符串常量。

if_.orelse = [ast.Print(dest=None,values=[ast.Str(s="not equal")],nl=True)]

执行ast

通过调用compile函数我们就可以执行该ast了。首先建立一个Module模块,然后compile得到代码,用exec就可以执行了。

mod = ast.Module(body = [assign_2,if_])

code = compile(mod,'','exec')
exec code

输出结果为2
如果将if判断改为 !=,NotEq,则会输出“not equal”!
ast也没有想象中那么难理解吧

总结

可以发现,ast也只是普通的python代码,知道Node的定义以后,不难手动写出来。

完整代码https://github.com/sgoal/myBlogCodes/blob/master/ast_code/ast_foo.py

资料:ast节点定义参考

你可能感兴趣的:(python)