Python不能不知的模組

發表於2016-09-06

之前我面試的時候,一般都會問一個問題:「能講講你日常開發中都用到了那些Python內建的模組嗎」?我為啥愛問這麼個問題呢:

1. 瞭解面試者日常的工作。

2. 瞭解面試者對技術的熱情和主動性。

3. 側面驗證面試者技術水平。

非常遺憾的是,絕大多數的面試者的回答我都不滿意。

那學會這些內建模組有多重要呢? 我舉五個例子吧:

1. 我做運維的時候,使用Python完成了一些打包和備份的指令碼,也就是把某個目錄壓縮成各種格式(tar.gz、tar.bz2、zip)。 這個指令碼其實打包壓縮的部分還是比較複雜的。直到我看到了這個:

有興趣的可以翻一下原始碼。你想要的說不定標準庫裡面已經實現。當然,有標準庫不滿足的額外需求,也可以參照它實現。
2. 你可能接觸過定時任務(crontab),它管理的任務很規矩,到點執行(當然精確度不那麼高)。現在設想你有更復雜的任務需求:這個任務是動態的,也就是不一定啥時候就來排上隊約定一個事件等著執行。這時候你可以想,這可以使用佇列(Queue模組)啊,嗯也不錯。難度再提高:加上優先順序策略並能取消某個指定的已經放入佇列的任務。現在思考下,這個怎麼實現?其實很多工程實踐的最好範例都在標準庫中。sched模組中的scheduler類就是一個這樣的通用的事件排程類。你可以學習它的實現。你問我它的實現多複雜?整個模組加上大幅的註釋才134行。

3. 學習Python的過程中,一開始我對於裝飾器contextmanager+yield怎麼都不懂。直到我看了contextmanager的原始碼, 其實非常簡單就懂了。它的docstring清楚地不能再清楚了:

4. 我之前使用多執行緒程式設計都這樣用,在好長一段時間裡面對於多程式和多執行緒之前怎麼選擇都搞得不清楚。看多了開源專案程式碼,我發現了好多人在用multiprocessing.dummy這個子模組,「dummy」這個詞本身好奇怪,我決定去看多程式(multiprocessing)庫的程式碼。「咦!怎麼和多執行緒的介面一樣呢」。後知後覺的我看到文件中這樣說:

恍然大悟!!!如果分不清任務是CPU密集型還是IO密集型,我就用如下2個方法分別試:

哪個速度快就用那個。從此以後我都儘量在寫相容的方式,這樣在多執行緒/多程式之間切換非常方便。
5. 13-14年間,Flask還沒怎麼火,那時候裝飾器風格的Web框架還有一個Bottle。我當時就直接想去看Bottle程式碼,發現一上來import了一堆模組,你先感受下bottle/bottle.py at master · bottlepy/bottle · GitHub ,第一感覺就是懵啊,這都是幹什麼的啊,為什麼要用啊?這就是促使我去看標準庫實現最重要的原因:學會了我才能更好的看懂別人寫的程式碼。

但是不是所有的標準庫都要一視同仁的看呢?你可以設定優先順序,先看那些不可不知道的模組。我在這裡列一下,並對它的用途和其中重要的類、函式的作用加以說明等。要是每個都寫例子實在太多太密集,怕大家看不下去,我都用外部連結了。

1. argparse。 用來替代optparse的命令列解析庫。如果你考慮用更直觀的,推薦docopt,它使用docstring所見即所得實現命令列解析。
2. collections。 包含了一些額外的資料型別。其中的OrderedDict(有序列的字典)、defaultdict(帶有預設值的字典)、namedtuple(通過建立帶有欄位屬性的元組子類)和deque(高效實現插入和刪除操作的雙向列表)非常常用。
3. functools。 這個模組有一些非常有用的工具,其中的partial(偏函式)、wraps(將被包裝函式的資訊拷貝過來)、total_ordering(只需要定義2個__XX__方法就可實現物件對比的類裝飾器)、cmp_to_key(將老式的比較函式轉化為關鍵字函式)非常常用。
4. glob。 檔名的shell模式匹配,你不用遍歷整個目錄判斷每個檔案是不是符合,使用glob一句話就解決。
5. multiprocessing。多程式模組,這重要性就不說了。
6. os。應該是日常工作最常用的模組了,你是否瞭解它裡面所有的函式和實現呢?舉個例子,獲取環境變數,我之前這樣用:

讀完原始碼之後我學了一招:

好吧,省了5個字元。
7. Queue。這個模組用於多執行緒程式設計,它是一個執行緒安全的FIFO(先進先出)的佇列實現。如果是多程式程式設計,選用multiprocessing.queues中的Queue、SimpleQueue、JoinableQueue這三個佇列實現。
8. SimpleHTTPServer。最簡單地HTTP Server實現。不使用Web框架,一句:

就可以執行起來靜態服務。平時用它預覽和下載檔案太方便了。
9. subprocess。 如果你還被某些書籍引導使用os.system或者os.popen等模組,現在是放棄它們的時候了,這個模組會滿足你絕大多數的系統命令執行、執行結果獲取和解析等需求。其中最有用的是call(執行系統命令)、check_call(執行結果不為0則丟擲異常)、check_output(最方便的獲取執行的輸出的函式)、Popen+PIPE(支援管道的多命令執行)。
10. threading。多執行緒模組,重要性也不必說。

當然啦,看的過程中還要多練習,也可以通過對應模組的測試程式碼瞭解模組。

相關文章