也許在Python編碼風格指導(PEP8)中最有爭議的一部分要數每行程式碼不超過80個字元的限制。沒錯,實際上是79個字元,但我使用80個字元,這個大概數,它是給程式設計師的一個參考值。
古老的VT100終端
現在很多軟體公司採用的編碼規範基本是PEP8,但每行80個字元的限制除外。GitHub上的專案,大多數都遵循PEP8規範(這一點似乎達到了高度的統一),但遵守80個字元限制的很少。在一些有明確規定的規範標準中,這個限制可能會增加(100或120),甚至完全刪除。這樣做常長見的理由是:我們已經不是使用VT100終端程式設計的年代了,我們有了更大,更高解析度的螢幕。這是事實,但我發現,在Python編碼中採用這個80個字元的規範,配合空格的使用,這會讓我們的程式碼更急湊,更可讀。
有一點你可以看出,在自然情況下,Python語句的長度一般會佔大概35-60個字元(不包括縮排)。更長的語句很少見。如果突然有一個句子比其它的要長很多,會顯得很突兀,不好看。同樣,使用強制性的空格來增加行寬能夠從視覺上幫助你最佳化減少巢狀迴圈的層數,一般的建議是重構程式碼不要讓縮排多於4層。
例如,把下面這個:
def search(directory, file_pattern, path_match, follow_symlinks=True, output=True, colored=True): ''' Search the files matching the pattern. The files will be returned, and can be optionally printed ''' pattern = re.compile(file_pattern) results = [] for root, sub_folders, files in os.walk(directory, followlinks=follow_symlinks): # Ignore hidden directories if '/.' in root: continue # Search in files and subfolders for filename in files + sub_folders: full_filename = os.path.join(root, filename) to_match = full_filename if path_match else filename match = re.search(pattern, to_match) if match: # Split the match to be able to colorize it # prefix, matched_pattern, sufix smatch = [to_match[:match.start()], to_match[match.start(): match.end()], to_match[match.end():]] if not path_match: # Add the fullpath to the prefix smatch[0] = os.path.join(root, smatch[0]) if output: print_match(smatch, colored) results.append(full_filename) return results
和這個比較:
def search(directory, file_pattern, path_match, follow_symlinks=True, output=True, colored=True): ''' Search the files matching the pattern. The files will be returned, and can be optionally printed ''' pattern = re.compile(file_pattern) results = [] for root, sub_folders, files in os.walk(directory, followlinks=follow_symlinks): # Ignore hidden directories if '/.' in root: continue # Search in files and subfolders for filename in files + sub_folders: full_filename = os.path.join(root, filename) to_match = full_filename if path_match else filename match = re.search(pattern, to_match) if match: # Split the match to be able to colorize it # prefix, matched_pattern, sufix smatch = [to_match[:match.start()], to_match[match.start(): match.end()], to_match[match.end():]] if not path_match: # Add the fullpath to the prefix smatch[0] = os.path.join(root, smatch[0]) if output: print_match(smatch, colored) results.append(full_filename) return results
在第一段程式碼裡會出現捲軸,但即使是沒有出現捲軸,這程式碼表現的也不美觀,視覺上不平衡。第二段程式碼看起來更好,更容易閱讀。
另 外重要的一點是,我可以在螢幕上顯示更多的東西。很多時候我們都需要螢幕上同時看一個檔案的多個地方,或多個檔案的內容。我喜歡的實現這個目的的方法是讓 它們按列排列。如果整個檔案有80個寬度的限制,程式碼會有一個很好的呈現,我不用擔心程式碼在編輯器裡會否自動折行,不用去麻煩配置編輯器。如果我需要使用 vim在命令列裡快速編輯一個檔案,就不用擔心檔案的寬度。能專注於程式碼。
唯一有問題的是使用Django的時候。當使用Django框架,你需要使用很多像這樣的呼叫:
ThisIsMyModel.objects.find(field1=value1, field2=value2).count()
在有縮排的程式碼裡,一個‘最小’的model函式呼叫都會讓你沒有多少剩餘空間…但我仍然堅持相同的原則,儘量讓程式碼表現的清晰可讀,但這比起其它Python程式碼來要難的多。
所以,即使這個限制最初的願望已經和現在完全不符合,我仍然覺得這個限制能幫助我寫出更可讀緊湊的程式碼。我是一個要求“可讀性”的狂熱分子,我甚至認為程式碼的可讀性是一個最重要的需要考慮的方面,程式設計師應該在任何時候都銘記這一點。