編寫高質量代碼--改善python程序的建議(一)


原文發表在我的博客主頁,轉載請注明出處!

初衷

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個字符
  • 空格的使用要能夠在需要強調的時候警示讀着,在疏松關系的實體間起到分隔作用,而在具有緊密關系的時候不要使用空格,具體如下:
  1. 二元運算符(賦值(=),比較(==,<, >, !=, <>, <=, >=, in, not in, is, is not),布爾運算(and, or, not))的左右兩邊應該有空格
  2. 逗號和分號前不要使用空格
  3. 函數名和左括號之間、序列索引操作時序列名和[]之間不需要空格,函數的默認參數兩側不需要空格
  4. 強調前面的操作符的時候使用空格。

建議五:編寫函數的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個建議


免責聲明!

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



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