開發效率,關乎三類對象,也就是閱讀者、編程者和機器。他們的優先級是閱讀者的體驗 >> 編程者的體驗 >> 機器的體驗。html
很多的編程規範,原本就是爲了優化讀者體驗而存在的。舉個例子,對於命名原則,我想不少人應該都有所理解,PEP8 第 38 條規定命名必須有意義,不能是無心義的單字母。如:git
錯誤示例 if (a <= 0): return elif (a > b): return else: b -= a # 正確示例 if (transfer_amount <= 0): raise Exception('...') elif (transfer_amount > balance): raise Exception('...') else: balance -= transfer_amount
再舉一個例子,Google Style 2.2 條規定,Python 代碼中的 import 對象,只能是 package 或者 module。github
#錯誤示例 from mypkg import Obj from mypkg import my_func my_func([1, 2, 3]) # 正確示例 import numpy as np import mypkg np.array([6, 7, 8])
#錯誤示例 result = [(x, y) for x in range(10) for y in range(5) if x * y > 10]
# 正確示例 result = [] for x in range(10): for y in range(5): if x * y > 10: result.append((x, y))
一些危險的編程風格,不只會影響程序正確性,也容易成爲代碼效率的瓶頸。好比, is 和 ==的使用區別。is是比較對象的內存地址。所以在比較整數的地址時要注意。編程
#################實驗證實,下面代碼只在終端中執行Python命令行時纔有效,而在執行腳本時整型的數據都會分配同一個空間 #錯誤示例 x = 27 y = 27 print(x is y) #True x = 721 y = 721 print(x is y) #False #以上的代碼的改爲==,確保是對比對象的值。 #正確示例 x = 27 y = 27 print(x == y) x = 721 y = 721 print(x == y)
再看 == ,當比較的是對象或者None時,有可能就會出乎意料,由於==的結果,取決於__eq__() 方法的具體實現app
#錯誤示例 class MyObject(object): def __eq__(self, other): if other: return self.field == other.field return True x = MyObject() print(x == None)
若是要與None比較時,永遠要使用is和is notide
# 正確示例 x = MyObject() print(x is None) 正確示例 def pay(name, salary=None): if salary is not None: salary = 11 print(name, "is compensated", salary, "dollars")
再提一個錯誤示範oop
#錯誤示例 adict = {i: i * 2 for i in xrange(10000000)} for key in adict.keys(): print("{0} = {1}".format(key, adict[key]))
keys() 方法會在遍歷前生成一個臨時的列表,致使上面的代碼消耗大量內存而且運行緩慢。正確的方式,是使用默認的 iterator。默認的 iterator 不會分配新內存,也就不會形成上面的性能問題:性能
# 正確示例 for key in adict:
摘自 《Python核心技術與實戰》專欄優化