這兩天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 space和space to tab,如果對的那段代碼做tab to space,代碼列對齊基本不變,箭頭都變成點,但是執行結果是a;二是,在 設定-喜好設定-語言下可以選上“以空格代替”,這樣以後每次按tab鍵都會自動轉換為空白格。
其他的編輯器,也有對應的一些處理技巧,比如,列表中有人提出,對VIM可以這樣設定:
set list
set listchars=tab:\|\ ,trail:-,nbsp:_
更多的編輯器特性,google上面應該還有很多,這裡就不贅述了。
處理好代碼縮排的問題,應該算是python的基本功吧。