Python 坑爹之 代碼縮進


建議:統一使用空格!!!!!!!!!不要Tab

 

Python代碼縮進

 

這兩天python-cn郵件列表有一條thread發展的特別長,題目是《python的代碼縮進真是坑爹》(地址),樓主在一台電腦上用KOMODO寫的代碼到另一台電腦上就不能運行了,調試后才發現是代碼縮進的問題,為此樓主表示“真是火大”!而之后的回復,可想而知,批判樓主、教育樓主、鄙視樓主等的人絕不是少數(畢竟是python郵件列表,都是python開發者、愛好者嘛)。

要求嚴格的代碼縮進是python語法的一大特色,就像C語言家族(C、C++、Java、C#等等)中的花括號一樣重要,在大多數場合還有必要。在很多代碼規范里面也都有要求代碼書寫按照一定的規則進行換行和代碼縮進,但是這些要求只是純粹是方便人(程序員)來閱讀、使用或修改的,對於編譯器或者解釋器而言,完全是視而不見的。但是對Python解釋器而言,每行代碼前的縮進都有語法和邏輯上的意義。Python的這個特性,也經常在Python使用者和非Python使用者中引起爭論。

Python的代碼縮進之起源,有人說事繼承於ABC(沒聽過但感覺很古老的語言),有人說是避免花括號,我猜可能是python發明者一時心血來潮的決定,大概也只有他能解釋這個問題。不管怎樣,作為發展了十余年的一名語言,這條語法規則已經不大可能改變了。

實際上,嚴格要求(強制)的代碼縮進,就像一把雙刃劍,有好處也有壞處。好處顯而易見,在嚴格要求的代碼縮進之下,代碼非常整齊規范,賞心悅目,提高了可讀性,在一定程度上也提高了可維護性。有人說,這種約束,對團隊開發非常有利,當然,也不見得,這就要看強制代碼縮進的壞處。Python嚴格的代碼縮進,對於從其他語言轉過來的人(現在計算機和相關專業第一門語言一般都是C/C++或Java吧,他們的語法風格基本是一直的),可能要適應一段時間。代碼縮進十分嚴格,如果不按規律辦事,不小心的話就會出現語法錯誤,比如unexpected indent之類的。甚至有時也會出現邏輯錯誤。

在實際情況中,由於代碼縮進而出現語法錯誤或邏輯錯誤,在我看來有這兩種主要情況,一是混用tab和空格縮進,二是編輯器對縮進的處理各異。這里給出一個例子,代碼是這樣的:

圖中使用的Notepad++編輯器,箭頭代表一個tab,點表示一個空格,默認情況下不會顯示箭頭和點,需要專門在視圖-顯示符號-顯示空格和制表符 中啟用這個功能。如果沒有箭頭和點,一般認為執行結果應該是顯示a,實際是顯示a、c,原因很簡單,1個tab,python會認為是8個空格。如果換成其他編輯器,可能print 'c'就不會和print 'b'同列顯示了。對於同一個文本,簡單的修改,不同編輯器做保存,也可能導致縮進出現不同。

我覺得為了避免因代碼縮進而產生不必要的麻煩,寫python代碼應該,使用唯一的縮進方式(要么tab,要么空格),使用固定和統一的編輯器,此外,還應該利用好編輯器的一些特性。對於notepad++而言,除了上面所說的顯示空格和制表符外,還有兩個特性可以使用:一是,編輯菜單下的blank operation有兩個選項tab to spacespace to tab,如果對上圖的那段代碼做tab to space,代碼列對齊基本不變,箭頭都變成點,但是執行結果是a;二是,在 設置-首選項-語言下可以選上“以空格代替”,這樣以后每次按tab鍵都會自動轉換為空格。

其他的編輯器,也有對應的一些處理技巧,比如,列表中有人提出,對VIM可以這樣設置:

set list
set listchars=tab:\|\ ,trail:-,nbsp:_

更多的編輯器特性,google上面應該還有很多,這里就不贅述了。

處理好代碼縮進的問題,應該算是python的基本功吧。

 

Python腳本運行出現語法錯誤:IndentationError: unindent does not match any outer indentation level

 

【問題】 
一個python腳本,本來都運行好好的,然后寫了幾行代碼,而且也都確保每行都對齊了,但是運行的時候,卻出現語法錯誤: 
IndentationError: unindent does not match any outer indentation level

【解決過程】 
1.對於此錯誤,最常見的原因是,的確沒有對齊。但是我根據錯誤提示的行數,去代碼中看了下,沒啥問題啊。 
都是用TAB鍵,對齊好了的,沒有不對齊的行數啊。 
2.以為是前面的注釋的內容影響后面的語句的語法了,所以把前面的注釋也刪除了。 
結果還是此語法錯誤。 
3.后來折騰了半天,突然想到了,把當前python腳本的所有字符都顯示出來看看有沒有啥特殊的字符。

當前用的文本編輯器Notepad++,好像有個設置,可以顯示所有的字符的。 
找到了,在: 
視圖 -> 顯示符號 -> 顯示空格與制表符

notepad   顯示空格與制表符

然后就看出問題來了: 
原來錯誤的行數是1580行:

python error line

但是源碼的1580行的對齊用的是點點點的空格,是和前面的幾行的對齊所用的箭頭表示的TAB鍵,是不匹配的,即代碼的對齊,混用了TAB鍵和空格:

1580 space and tab mixed
而新的Python語法,是不支持的代碼對齊中,混用TAB和空格的。所以出現上述錯誤提示了。

知道原因了,解決起來就簡單了: 
去把對應的TAB,都改為空格,統一一下對齊的風格,即可。 
在Notepad++中,去: 
設置->首選項:

設置 首選項

語言->以空格取代(TAB鍵):

語言 以空格取代Tab

即可實現,對於以后每次的TAB輸入,都自動轉換為4個空格。

【總結】

Python中遇到IndentationError,以后第一時間就要想到,是不是由於TAB鍵和空格混搭使用了。

估計很多人也都是此類原因導致的。記得統一一下就好。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM