Python ast 學習筆記1 手動建ast

2021-07-28 15:01:40 字數 2620 閱讀 8513

python中的ast模組是非常強大的模組,可以用來修改python原始碼,或者分析python原始碼。為了學習ast模組,先來手動建立乙個ast熟悉熟悉。

將用ast來表示下列**:

foo = 2

if foo == 2:

print foo

else:

print

"not equal"

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語句的定義為:

test為測試節點,body是一串行的節點,orelse也是一串行的節點。

class if(test, body, orelse)
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此處只有一句話,就是print定義為print(dest, values, nl),dest為print>>dest,此處我們不需要。values要列印的值,nl為是否換行。

if_.body = [ast.print(dest=none,values=[copy(use_foo)],nl=true)]
了解上面以後,else部分就比較簡單了。其中str為字串常量。

if_.orelse = [ast.print(dest=none,values=[ast.str(s="not equal")],nl=true)]
通過呼叫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的定義以後,不難手動寫出來。

完整**

學習筆記 12306 手動登入解析(1)

coding utf 8 import urllib2 import urllib 驗證碼登入同步 import cookielib import ssl 證書驗證 請求驗證碼 c cookielib.lwpcookiejar 生成乙個儲存cookie的物件 cookie urllib2.httpc...

學習筆記1

struct test test int x void fun class test1 test1 int x void fun int main void test1 a 行1 a.fun 行2 test1 b 行3 b.fun 行4 test c 行5 c.fun 行6 test d 行7 d....

學習筆記1

1 字串原地逆序 使用臨時變數 void reverse string s 5 求平均值 避免溢位 int f int x,int y 6 楊氏矩陣 bool young int a m n int x return false 7 十進位制轉十六進製制 string decimaltohexade...