《Python核心技術與實戰》筆記3

ersaijun發表於2020-12-19

《Python核心技術與實戰》筆記1
《Python核心技術與實戰》筆記2
《Python核心技術與實戰》筆記3

編碼風格

  • 《8 號 Python 增強規範》(Python Enhacement Proposal #8),簡稱 PEP8;

  • # 錯誤示例
    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:
    
  • PEP 8 規範告訴我們,請選擇四個空格的縮排,不要使用 Tab,更不要 Tab 和空格混著用。

  • PEP 8 規定,全域性的類和函式的上方需要空兩個空行,而類的函式之間需要空一個空行

  • Python 中我們可以使用#進行單獨註釋,請記得要在#後、註釋前加一個空格。

合理利用assert

assert 1 == 2
assert 1 == 2,  'ersaijun:assertion is wrong'
# 丟擲異常 AssertionError
# 輸出
AssertionError: ersaijun:assertion is wrong
def func(input):
    assert isinstance(input, list), 'input must be type of list'
    # 下面的操作都是基於前提:input 必須是 list
    if len(input) == 1:
        ...
    elif len(input) == 2:
        ...
    else:
        ... 
  • 不能濫用 assert。很多情況下,程式中出現的不同情況都是意料之中的,需要我們用不同的方案去處理,這時候用條件語句進行判斷更為合適。而對於程式中的一些 run-time error,請記得使用異常處理。

上下文管理器context manager和With語句

  • 在任何一門程式語言中,檔案的輸入輸出、資料庫的連線斷開等,都是很常見的資源管理操作。但資源都是有限的,在寫程式時,我們必須保證這些資源在使用過後得到釋放,不然就容易造成資源洩露,輕者使得系統處理緩慢,重則會使系統崩潰。
  • 在 Python 中,對應的解決方式便是上下文管理器(context manager)。上下文管理器,能夠幫助你自動分配並且釋放資源,其中最典型的應用便是 with 語句。
for x in range(10000000):
    with open('test.txt', 'w') as f:
        f.write('hello')

基於類的上下文管理器

class FileManager:
    def __init__(self, name, mode):
        print('calling __init__ method')
        self.name = name
        self.mode = mode 
        self.file = None
    # 返回需要被管理的資源
    def __enter__(self):
        print('calling __enter__ method')
        self.file = open(self.name, self.mode)
        return self.file
    # 一些釋放、清理資源的操作
    # 方法“__exit__()”中的引數“exc_type, exc_val, exc_tb”,分別表示 exception_type、exception_value 和 traceback。當我們執行含有上下文管理器的 with 語句時,如果有異常丟擲,異常的資訊就會包含在這三個變數中,傳入方法“__exit__()”。
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('calling __exit__ method')
        if self.file:
            self.file.close()
            
with FileManager('test.txt', 'w') as f:
    print('ready to write to file')
    f.write('hello world')
    
## 輸出
calling __init__ method
calling __enter__ method
ready to write to file
calling __exit__ method

基於生成器的上下文管理器

from contextlib import contextmanager
 
@contextmanager
def file_manager(name, mode):
    try:
        f = open(name, mode)
        yield f
    finally:
        f.close()
        
with file_manager('test.txt', 'w') as f:
    f.write('hello world')
  • 基於類的上下文管理器更加 flexible,適用於大型的系統開發;
  • 而基於生成器的上下文管理器更加方便、簡潔,適用於中小型程式。
  • 自行定義相關的操作對異常進行處理,而處理完異常後,也別忘了加上“return True”這條語句,否則仍然會丟擲異常。

單元測試

pdb & cProfile:除錯和效能分析

a = 1
b = 2
import pdb
pdb.set_trace()
c = 3
print(a + b + c)
  • pdb自帶的一個除錯庫。它為 Python 程式提供了互動式的原始碼除錯功能,是命令列版本的 IDE 斷點偵錯程式
  • https://docs.python.org/3/library/pdb.html#module-pdb
  • profile,是指對程式碼的每個部分進行動態的分析,比如準確計算出每個模組消耗的時間等。這樣你就可以知道程式的瓶頸所在,從而對其進行修正或優化。
  • pdb 為 Python 程式提供了一種通用的、互動式的高效率除錯方案;而 cProfile 則是為開發者提供了每個程式碼塊執行效率的詳細分析,有助於我們對程式的優化與提高。
  • https://docs.python.org/3.7/library/profile.html

相關文章