如何高效的閱讀Python第三方庫源碼
咪哥雜談

本篇閱讀時(shí)間約為 6 分鐘。
1
前言
前幾天拉個(gè)一個(gè) Python 學(xué)習(xí)小組的群,有些小伙伴已經(jīng)加進(jìn)來了。其中有個(gè)小伙伴提了一個(gè)問題,這是一個(gè)比較好的問題,所以有必要單獨(dú)拎出來寫篇文章。
PS:如果還有想進(jìn)群的小伙伴,可以公眾號后臺(tái)加下我的微信,拉你入群。
問題是這樣的:

引出了今天要聊的主題,接下來咱們就來談?wù)勥@個(gè)問題。以下方法,都是個(gè)人的做法,不一定適用于每一個(gè)人。但相信會(huì)有人和我一樣,認(rèn)為這樣的方法比較高效,所以分享下。
2
有目標(biāo)性的去學(xué)習(xí)
就像這位同學(xué)說到的,網(wǎng)上有人推薦去看各界大神 requests 的源碼,學(xué)習(xí)其編程風(fēng)格,然后揉入到自己的代碼編寫中,得以提升自己的編程境界。
但是往往有個(gè)問題,現(xiàn)成的第三庫已經(jīng)非常成熟,體系也異常龐大,哪里才是你應(yīng)該去看的,去學(xué)習(xí)的點(diǎn)?
說出來不怕大家笑話,其實(shí)就連我自己也沒有系統(tǒng)地看過 requests 庫的源碼。因?yàn)槲矣X得,無頭蒼蠅似的去看源代碼,帶來的記憶風(fēng)格也是混亂的,而且往往記不住!
所以,就像上圖中我的回答一樣,雖然我不會(huì)系統(tǒng)的學(xué)習(xí)去看,但是在具體用到某一方法時(shí),如果我對它的實(shí)現(xiàn)原理非常好奇,那此時(shí),我會(huì)跟進(jìn)去學(xué)習(xí),原作者當(dāng)時(shí)實(shí)現(xiàn)是一個(gè)怎樣的思路。
但,什么時(shí)候才能產(chǎn)生好奇心?就是接下來要說的大前提。
3
前提條件,會(huì)用
產(chǎn)生好奇心的有個(gè)大前提,就是你得會(huì)用啊!
其實(shí)在上面聊天記錄的下方,還有一個(gè)小伙伴給出了我想表述的大前提。

只有當(dāng)你熟悉了一個(gè)東西的時(shí)候,有時(shí)候才會(huì)對它背后的原理感興趣!
拿 requests 庫的 get 請求方法來說,你都不知道它的作用是干什么的,去看源碼學(xué)習(xí),你知道最終你自己看的到底是為了實(shí)現(xiàn)什么功能嘛!對吧。。。
4
實(shí)戰(zhàn)演示如何看源碼
熟悉我的人都知道一點(diǎn),能實(shí)戰(zhàn)就實(shí)戰(zhàn),絕不多BB。(實(shí)戰(zhàn)派!^_^)
給大家舉個(gè)我寫上篇文章時(shí)候的例子。PyQuery,這個(gè)庫,當(dāng)時(shí)我在看官方文檔時(shí),看到了這么一句話:

這句話什么意思呢?
上篇文章中,我們可以直接用 PyQuery 來構(gòu)造模擬發(fā)出請求,大家還記得吧!文章中,我還特意寫了一下,請求時(shí)它內(nèi)部的機(jī)制代碼。
為什么我會(huì)知道,它請求時(shí)內(nèi)置的機(jī)制呢?一是看了官方文檔,二是好奇心。
官方文檔的 Scraping 部分,紅框的意思是,默認(rèn)使用了 python 原生的 urllib 庫,如果你本地安裝了 requests 庫的話,它會(huì)直接使用 requests 庫進(jìn)行請求。
這是看了,官方文檔得知的信息,但看完了,我依然是好奇,作者到底是如何在代碼層面實(shí)現(xiàn)設(shè)計(jì)的。
下面請暫時(shí)記住這個(gè)問題,"官方文檔說的這段話的代碼具體是怎么實(shí)現(xiàn)的?"。帶著這個(gè)問題繼續(xù)往下看。
debug ,斷點(diǎn)調(diào)試大法好!!
1. 好奇入口處打斷點(diǎn):

創(chuàng)建對象時(shí),必經(jīng)過 __init__ 方法,所以繼續(xù)進(jìn)去看看。PyCharm 直接 alt+鼠標(biāo)點(diǎn)一下,就能調(diào)到底層源碼。然后開啟debug模式,F(xiàn)7 step into,進(jìn)去。不會(huì) debug ,看下之前寫的這篇文章《新手必會(huì),pycharm的調(diào)試功能(史上最詳篇)》!
2. __init__ 里繼續(xù)斷點(diǎn):

在判斷 kwargs 之前,可以看到處理了一些操作,比如在 pq() 傳參時(shí),第一個(gè)參數(shù)默認(rèn)給到形參 url 上。這些都是 Python 的一些基礎(chǔ),不會(huì)的話,需要自己惡補(bǔ)一下了!之前小課堂都有介紹。

可以看到 debug 到判斷 kwargs 時(shí), key 為 url ,value 則為我們創(chuàng)建對象時(shí)傳入的地址。
繼續(xù)往下看。

kwargs 本身是個(gè) dict 類型,用 pop 方法把我們傳入的地址賦值給了 url 變量。如果在 kwargs 沒有 opener 這個(gè)key,則直接走到了我紅框畫的地方,并將 url 傳進(jìn)去。
繼續(xù)進(jìn)入這個(gè)方法看看:

有個(gè) HAS_REQUEST 變量,點(diǎn)一下看看:

看到了沒,精華之處,很靈活的寫法:
try:import requestsHAS_REQUEST = Trueexcept ImportError:HAS_REQUEST = False
通過抓取異常,來進(jìn)行靈活庫的判斷。如果你有 requests 庫,則變量 HAS_REQUEST = True,否則是 False。
這塊的實(shí)現(xiàn)思想,是不是可以從原作者編寫的代碼中學(xué)習(xí)下,后續(xù)運(yùn)用到自己的代碼編寫中。
最后,如果有 requests 庫,就走到了相應(yīng)的方法里,最終返回 requests 請求到的源代碼。

反之,則用 Python 自帶的 urllib 庫去模擬請求。

5
總結(jié)
好了,簡單的總結(jié)一下。
我個(gè)人推崇的方法是,攜帶著自己的具體問題去學(xué)習(xí),看源碼也是一個(gè)道理。
一步步的去從好奇點(diǎn)出發(fā),逐步 debug 來挖到自己最關(guān)注的地方。然后學(xué)習(xí)作者的編程思維,加以記憶,利用到自己后續(xù)的代碼編寫中。
其實(shí)關(guān)于帶著目標(biāo)去學(xué)習(xí)這個(gè)方法,適用于大部分場景。還記得剛開始工作時(shí),解決工作中問題,去學(xué)習(xí)編程,那段時(shí)間是我進(jìn)步最快的時(shí)光。
嗯,到這里就結(jié)束了,看完本篇的你,有沒有收獲到什么呢?歡迎下方留言區(qū)留言交流呀!

Python玩轉(zhuǎn)高德地圖API(一)
你點(diǎn)的每個(gè)在看,我都認(rèn)真當(dāng)成了喜歡