原文發表在我的博客主頁,轉載請注明出處!
初衷
python是一個入門十分容易的編程語言,但是想要寫好python卻是一件不容易的事情,如果不是專業使用python的人,只是將python作為一個腳本語言或者用來處理數據,到了掌握基本的語法之后,便不再尋求進步。但是相信每個學習python的人都知道pythonic這個單詞,這個詞語很難定義,全靠心領神會,但大家心中都認同Tim Peters的《The Zen of Python》中提到的幾點:
- 美勝丑,顯勝隱,簡勝雜,雜勝亂,平勝陡,疏勝密
- 找到簡單問題的一個方法,最好是唯一的方法
- 難以解釋的實現,源自不好的主意
使用python已經很久了,發現自己處在了一個上升的瓶頸,而我堅信讀書是解決這種問題的不二法門,所以寫一些讀書筆記,當然書中的有些內容我不敢苟同,所以也會加入自己的甄別和想法。
建議一:寫pythonic代碼
- 代碼風格
舉幾個常見的例子,相信大家就會理解
兩個變量交換:
a, b = b, a
遍歷容器:
for i in container:
do_sth_with(i)
安全的處理文件:
with open(path,"r") as f:
do_sth_with(f)
- 標准庫
寫pythonic需要對標准庫有充分的理解,特別是內置函數和內置數據類型,比如,對於字符串格式化,一般寫作這樣:
print 'Hello %s!' % ('Tom',)
這樣非常影響可讀性,數量多了之后,很難清楚哪一個占位符對應哪一個參數,所以最好這樣寫:
print 'Hello %(name)s!' % {'name':'Tom'}
這樣其實已經相當pythonic,但是想想%占位符,其實是從學習C語言的時候就深深扎根頭腦了,在python中,還有更加pythonic的寫法。
print '{greet} from {language}.'.format(greet = 'Hello world', language = 'Python')
其中str.format()非常清晰的表明了語句的意圖,稱為python最為推薦的字符串格式化方法。
- pythonic的庫或者框架
包和模塊的命令采用小寫、單數形式,而且短小。
包通常僅作為命名空間,如只包含空的__init__.py文件。
建議二:理解python和C語言的不同之處
- “縮進”與“{}”
- '與"
- 三元操作符 “?:”
python: X if X<Y else Y
C: X<Y:X:Y
- swith...case
上述的區別相信使用過python的人都清楚,所以不再贅述
建議三:在代碼中適當添加注釋
python中有三種形式的代碼注釋:塊注釋、行注釋以及文檔注釋
- 使用塊注釋或者行注釋的時候僅僅注釋哪些復雜的操作、算法,或者難以理解,不能一目了然的代碼
- 給外部可訪問的函數和方法(無論簡單與否)添加文檔注釋。注釋要清楚的描述方法的功能,並對參數、返回值以及可能發生的異常進行說明,使得外部調用它的人員僅僅看文檔注釋就能正確使用。較為復雜的內部方法也需要進行注釋。推薦的函數注釋如下:
def FuncName(parameter1, parameter2):
"""
Describe what this function does:
#such as "Find whether the special string is in the queue or not"
Args:
parameter1:parameter type, what is this parameter used for
parameter2:parameter type, what is this parameter used for
Returns:
return type, return value
"""
function body
···
···
- 頭文件中包含copyright申明、模塊描述等,如有必要,可以考慮加入作者信息以及變更記錄。
"""
Licensed Materials - Property of CorpA
(C) Copyright A Corp. 1999, 2011 All Rights Reserved
Copyright statement and purpose...
--------------------------------------------------------
File name :
Description :
Author:
Change Activity:
--------------------------------------------------------
"""
建議四:通過適當添加空行使代碼布局更為優雅、合理
- 在一組代碼表達完一個完整的思想后,應該用空白行進行間隔。如每個函數之間,導入聲明、變量賦值等。推薦在函數定義或者類定義之間空兩行,在類定義與第一個方法之間,或者需要進行語義分割的地方空一行。
- 盡量保持上下文語義的易理解性,如當一個函數需要調用另一個函數的時候,盡量將他們放在一起,最好調用者在上,被調用者在下。
- 避免過長的代碼行,每行最好不要超過80個字符。
- 空格的使用要能夠在需要強調的時候警示讀着,在疏松關系的實體間起到分隔作用,而在具有緊密關系的時候不要使用空格,具體如下:
- 二元運算符(賦值(=),比較(==,<, >, !=, <>, <=, >=, in, not in, is, is not),布爾運算(and, or, not))的左右兩邊應該有空格
- 逗號和分號前不要使用空格
- 函數名和左括號之間、序列索引操作時序列名和[]之間不需要空格,函數的默認參數兩側不需要空格
- 強調前面的操作符的時候使用空格。
建議五:編寫函數的4個原則*
- 函數設計要盡量短小
- 函數聲明要做到合理、簡單、易於使用
- 函數參數設計應該考慮向下兼容
- 一個函數只做一件事情,盡量保證函數語句粒度的一致性
建議六:將常量集中到一個文件
在python中如何使用常量呢,一般來說有一下兩種方式:
- 通過命名風格來提醒使用者該變量代表的意義為常量。如TOTAL,MAX_OVERFLOW,然而這種方式並沒有實現真正的常量,其對應的值仍然可以改變,這只是一種約定俗成的風格
- 通過自定義的類實現常量功能,這要求符合“命名全部為大寫”和“值一旦綁定便不可再修改”這兩個條件。可以通過異常來解決這個問題
class _const:
class ConstError(TypeError): pass
class ConstCaseError(ConstError): pass
def __setattr__(self, name, value):
if self.__dict__.has_key(name):
raise self.ConstError, "Can't change const. %s" %name
if not name.isupper():
raise self.ConstCaseError, \
'const name "%s" is not all uppercase' %name
self.__dict__[name] = value
import sys
sys.modules[__name__] = _const()
上面定義了一個類用於約束常量定義,定義常量方式如下(建議將所有的常量定義在一個文件constant.py中):
import const
const.COMPANY = "IBM"
...
當在其他模塊中引用這些常量時,按照如下方式進行即可:
from constant import const
print const.COMPANY
總結:本篇博客主要列舉了一些常見的編程准則,而其中列舉的一些建議不光可以用在python,在其他編程語言中同樣適用。
參考:編寫高質量代碼--改善python程序的91個建議