Requests源碼閱讀

image

很久之前閱讀的,差點忘了


一、_Requests模塊的作用

class _Request(urllib2.Request):
    """Hidden wrapper around the urllib2.Request object. Allows for manual
    setting of HTTP methods.
    """

    def __init__(self, url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None):
        urllib2.Request.__init__(self, url, data, headers, origin_req_host, unverifiable)
        self.method = method

    def get_method(self):
        if self.method:
            return self.method

        return urllib2.Request.get_method(self)

剛開始看時,不太注意注釋里面的英文,然后就看它作用是繼承urllib2.Request模塊并改寫一下get_method(),這里就有點迷糊了,改寫get_method()作用是什么。
于是去看了urllib2關(guān)于get_method()的文檔,文檔就一句話就沒有怎么留意,下面是文檔原話:

Request.get_method()
    Return a string indicating the HTTP request method. This is only meaningful for HTTP requests, and currently always returns 'GET' or 'POST'.

這句話說的是,返回一個指示HTTP請求的方法。只對HTTP請求有效,目前總是返回'GET'或者'POST'。使用過Requets的人都知道,Requests不僅僅有GET和POST請求,還有HEAD、POST、DELETE等請求,所以這里重寫了get_method,讓它自動根據(jù)傳進來的method進行hack(鉤子)方式的添加其它類型HTTP請求方式。一般直接使用urllib2,可以如下這樣實現(xiàn)其他類型請求:

import urllib2

request = urllib2.Request(uri, data=data)
request.get_method = lambda: 'PUT' # or 'DELETE'
response = urllib2.urlopen(request)

這是我第二次回顧源碼前面的細節(jié),真的要仔細看源碼和注釋才行,之前只是過了一遍。

二、Reqeusts中的認證模塊

if isinstance(auth, (list, tuple)):
    auth = AuthObject(*auth)
if not auth:
    auth = auth_manager.get_auth(self.url)
self.auth = auth

判斷auth是否list或者tuple類型,如果是,就調(diào)用自定義的自動選擇認證handlers模塊,
urllib2中認證相關(guān)的處理模塊主要有以下幾種:

HTTPBasicAuthHandler(password_mgr=None)             #處理與遠程主機的身份驗證
HTTPDigestAuthHandler(password_mgr=None)            
ProxyBasicAuthHandler(password_mgr=None)            # 處理與代理的身份驗證
ProxyDigestAuthHandler(password_mgr=None)

這些處理類都在urllib2中定義,看Requests源碼很多時候需要了解urllib2模塊的相關(guān)功能,需要閱讀請到這里Python2 urllib2模塊文檔 , 需要看該模塊的源碼的話,可以去Python3 urllib.request模塊源碼參看源碼。
如果沒有auth對象,則調(diào)用自定義的AuthManager類來注冊一個auth對象,關(guān)于AuthManager類,里面使用了單例模式,還有重寫了 HTTPPasswordMgr類的幾個函數(shù),細節(jié)請閱讀urllib.request模塊源碼中的HTTPPasswordMgr。

三、_get_opener()函數(shù)

handlers的處理都放在這里,要了解這個函數(shù),就必須了解urllib2怎么處理封裝Handlers,
Openers對象(一個urllib2.OpenerDirector的實例),如何構(gòu)建(build_opener)、如何安裝全局(install_opener)
(待改進)

四、代碼重構(gòu)

在v0.3.4版本中重構(gòu)了整個項目,使功能模塊更加清晰

0.3.4
+++++

* Urllib2 HTTPAuthentication Recursion fix (Basic/Digest)
* Internal Refactor
* Bytes data upload Bugfix

解決了urllib2模塊存在的認證問題,就是輸入錯誤的密碼認證,會無限循環(huán)認證下去,具體請看urllib2 Recursion issue.再看代碼重構(gòu)后的requests目錄下:

# 重構(gòu)后
requests
├── api.py            
├── async.py                # moneypatch 猴子補丁
├── core.py
├── __init__.py             # contextmanager
├── models.py               # 以前core.py中的代碼,主要是Request、Response類
├── monkeys.py              # 重寫urllib2相關(guān)類的實現(xiàn)
├── packages                # 第三方庫,關(guān)于上傳文件相關(guān)的。
│   ├── __init__.py
│   └── poster
│       ├── encode.py
│       ├── __init__.py
│       ├── streaminghttp.py
├── patches.py
└── structures.py           # 來自于 werkzeug 的多key字典之類的數(shù)據(jù)結(jié)構(gòu)


重構(gòu)前
├── requests
│   ├── async.py
│   ├── core.py             # 所有代碼都在這里
│   ├── __init__.py         # contextmanager
│   ├── packages            # 同上
│   │   ├── __init__.py
│   │   └── poster
│   │       ├── encode.py
│   │       ├── __init__.py
│   │       ├── streaminghttp.py
│   └── structures.py

這樣的確代碼清晰好多,比如重寫urllib2的類就可以全部放在monkeys.py,以后需要重寫其他標(biāo)準(zhǔn)庫的類也同樣放在里面,維護起來就方便很多

五、看Pull Request

其實,各種功能討論和bug修復(fù),都可以在PR里面看到更詳細的內(nèi)容,可以看到那些貢獻者的討論,還是有一點用的吧。。。
發(fā)現(xiàn)jgorset這個貢獻者很活躍,從版本0.。。。忘了, 就是很早的版本他都不斷提交PR,很多代碼結(jié)構(gòu)的重構(gòu)都是他PR上去的,應(yīng)該是個牛人。

v0.5.0
第五版改動還真是很大啊,搞得我都看得有點懵了,總的來說很多細節(jié)方面進行了優(yōu)化,
測試用例也有很大的改動,統(tǒng)一了測試使用的URL。

未完待續(xù)。。。。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 庫結(jié)構(gòu) 整體結(jié)構(gòu) 這是我第一次看源碼,版本為requests-2.18.4.說實話很吃力,有這幾個原因 英文水平不...
    _kkk閱讀 1,986評論 0 1
  • urllib and urllib2 區(qū)別 –博主提示:下面的是python2中的用法,python3需要做出相應(yīng)...
    sunnyRube閱讀 1,490評論 0 1
  • 基本爬蟲知識python庫urllib、urllib2、requests urllib、urllib2、reque...
    tenliu的簡書閱讀 507評論 0 4
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,694評論 1 32
  • 自從去電影院看了阿米爾汗的《外星醉漢pk地球神》之后,對印度電影一發(fā)不可收拾,每有必去電影院享受2-3個小時。 今...
    價值園閱讀 820評論 0 51

友情鏈接更多精彩內(nèi)容