【Python】解析Python的縮進規則
Python中的縮進(Indentation)決定了代碼的作用域範圍。這一點和傳統的c/c++有很大的不同(傳統的c/c++使用花括號{}符,python使用縮進空格)。
每行代碼中開頭的空格數(whitespace)用於計算該行代碼的縮進級別(Indentation level),註意一個Tab等於8個空格(Space),縮進級別為0表示無縮進空格。
Python中的每一條語句都有一個縮進級別,並且縮進級別會使用棧的數據結構進行存儲。在開始讀取文件之前,0(表示縮進級別為0,無縮進)會被首先壓入棧中。然後從文件開頭到末尾,依次讀取每行邏輯代碼,每行邏輯代碼的縮進級別都會和棧頂值進行比較,如果相等,那麽什麽都不會發生;如果比棧頂值大的話,那麽該行邏輯代碼的縮進級別就會被壓入棧中,同時會生成一個縮進標記(INDENT LEVEL);如果比棧頂值小的話,那麽棧中所有比該行邏輯代碼縮進級別大的值都會從棧中移除,並且還會生成一個擴展標記(DEDENT LEVEL)。
下面是一個正確的縮進案例:
def perm(l):#0 # Compute the list of all permutations of l if len(l) <= 1:# 1 return [l]# 2 r = []# 3 for i in range(len(l)):# 4 s = l[:i] + l[i+1:]# 5 p = perm(s)# 6 for x in p:# 7 r.append(l[i:i+1] + x)#8 return r# 9
上面的#0行,縮進0個字符,由於文件讀取之前0已經被壓入棧中了,所以棧中的數據不會發生改變。#1縮進4個字符,4被壓入棧中。#2縮進18個字符,18被壓入棧中。#3縮進4個字符,18被彈出棧,棧頂值又為4了。#4和#3縮進一樣,所以不更新棧數據。#5縮進13個字符,所以13被壓入棧中。#5、#6和#7的縮進一樣,不更新棧數據。#8縮進14個字符,14被壓入棧中。#9的縮進4個字符,所以棧中的13和14都會彈出,棧頂值又恢復為4。
下面是一個錯誤的案例
def perm(l): #1 error: first line indentedfor i in range(len(l)): #2 error: not indented s = l[:i] + l[i+1:] p = perm(l[:i] + l[i+1:]) #3 error: unexpected indent for x in p: r.append(l[i:i+1] + x)#4 return r #5 error: inconsistent dedent
#1、#2和#3處的錯誤解釋的很清楚了。#5的縮進級別在棧中找不到所以出錯,#5處的縮進級別是14,比它的上面一行縮進級別18,所以在#5處應該進行出棧處理,但是在棧中找不到14這個級別,所以出錯。
又比如:
if True: print("hello girl") else: print("hello boy") print("end")
最後一行代碼的縮進級別是1,而且比上一行代碼的縮進級別小,所以應該出棧處理,但是在出站的時候找不到棧中以前有1的級別,所以報錯。
要修改的話,只需要將最後一行的空格去掉就可以。
參考文章:
https://docs.python.org/2.0/ref/indentation.html
【Python】解析Python的縮進規則