国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Python 的異步 IO:Aiohttp Client 代碼分析

fai1017 / 2691人閱讀

摘要:的異步代碼分析是的一個框架,基于,所以叫。不可避免的,可讀性會比較差。想找教程的話,請移步官方教程,寫得還是挺不錯的。建議不要直接使用,而只把它當成的一個樣例。

Python 的異步 IO:Aiohttp Client 代碼分析

Aiohttp 是 Python 的一個 HTTP 框架,基于 asyncio,所以叫 Aiohttp。

我主要是看源碼,想理解它的設計,所以附上了類圖與時序圖。不可避免的,可讀性會比較差。
想找教程的話,請移步 官方教程,寫得還是挺不錯的。

一個例子

下面這個例子,通過 HTTP GET 列出 GitHub 的 public events:

import asyncio
import aiohttp

async def main():
    async with aiohttp.ClientSession() as session:
        async with session.get("https://api.github.com/events") as resp:
            print(resp.status)
            print(await resp.text())

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Response 是一個 JSON 格式的文本:

[
  {
    "id": "6888907432",
    "type": "PushEvent",
    "actor": {
      "id": 3956266,
      "login": "sekineh",
      "display_login": "sekineh",
      "gravatar_id": "",
      "url": "https://api.github.com/users/sekineh",
      "avatar_url": "https://avatars.githubusercontent.com/u/3956266?"
    },
    ...
]

ClientSession 是一個 Asynchronous Context Manager,所以搭配 async with 語句一起使用。像下面這樣應該也是可以的:

async def main():
    session = aiohttp.ClientSession()
    ...
    await session.close()

不過肯定是不推薦的,就當是幫助理解吧。

ClientSession.get() 返回一個 ClientResponse 對象,通過 text() 方法,可以拿到 response 的文本:

print(await resp.text())

當然,text() 是一個協程:

    @asyncio.coroutine
    def text(self, encoding=None, errors="strict"):
        """Read response payload and decode."""
        ...
Connector

ClientSession 依賴 Connector 來創建連接,缺省為 TCPConnector,它繼承自 BaseConnector,此外還有 UnixConnector(應該是 Unix Domain Socket)。

Connector 的接口比較簡單,主要提供了 connect() 方法(也是協程):

    @asyncio.coroutine
    def connect(self, req):
        """Get from pool or create new connection."""
        ...

以及 close() 方法:

    def close(self):
        """Close all opened transports."""
        ...
ConnectionKey

ClientRequest 有個屬性 connection_key

class ClientRequest:
    @property
    def connection_key(self):
        return ConnectionKey(self.host, self.port, self.ssl)

它是一個 namedtuple

ConnectionKey = namedtuple("ConnectionKey", ["host", "port", "ssl"])

hostportssl 三個元素組成,這三個元素可以唯一定義一個連接,所以叫 ConnectionKey
文章開頭的那個例子中,ConnectionKey 為:

ConnectionKey(host="api.github.com", port=443, ssl=True)
全局函數 request()

Aiohttp 為 Client 程序提供了一個全局函數 request(),用法如下:

async def main():
    resp = await aiohttp.request("GET", "http://python.org/")
    print(resp)
    
loop = asyncio.get_event_loop()
loop.run_until_complete(main())

可見 request() 只是 ClientSession 的一個簡單封裝,其步驟大致為:

創建 TCPConnector

創建 ClientSession

調用 ClientSession._request()

建議不要直接使用 request(),而只把它當成 ClientSession 的一個樣例。因為 Aiohttp 官方文檔是 這樣說的:

Don’t create a session per request. Most likely you need a session per application which performs all requests altogether.

A session contains a connection pool inside, connection reusage and keep-alives (both are on by default) may speed up total performance.

即,一個 request 用一個 session,太浪費;通常是一個 application 用一個 session。

一些小問題

我經常發現一個變量,明明可以是局部變量,卻被當成了成員變量。

Request 里放了一個 response?

class ClientRequest:
    def send(self, conn):
        ...
        self.response = self.response_class(
            self.method, self.original_url,
            writer=self._writer, ...
        )

        self.response._post_init(self.loop, self._session)
        return self.response

self.responseClientRequest 其他地方并沒有用到,是否可以改成局部變量?

ClientResponse.start() 里的 _protocol 應該用局部變量吧?

class ClientResponse:
   @asyncio.coroutine
    def start(self, connection, read_until_eof=False):
        """Start response processing."""
        self._closed = False
        self._protocol = connection.protocol
類圖

時序圖

The End

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/44503.html

相關文章

  • 基于Sanic微服務基礎架構

    摘要:在中,官方的異步協程庫正式成為標準。本項目就是以為基礎搭建的微服務框架。使用做單元測試,并且使用來避免訪問其他微服務。跟蹤每一個請求,記錄請求所經過的每一個微服務,以鏈條的方式串聯起來,對分析微服務的性能瓶頸至關重要。 介紹 使用python做web開發面臨的一個最大的問題就是性能,在解決C10K問題上顯的有點吃力。有些異步框架Tornado、Twisted、Gevent 等就是為了解...

    seasonley 評論0 收藏0
  • Python爬蟲入門教程 7-100 蜂鳥網圖片爬取之二

    摘要:蜂鳥網圖片簡介今天玩點新鮮的,使用一個新庫,利用它提高咱爬蟲的爬取速度。上下文不在提示,自行搜索相關資料即可創建一個對象,然后用該對象去打開網頁。可以進行多項操作,比如等代碼中等待網頁數據返回創建線程,方法負責安排執行中的任務。 1. 蜂鳥網圖片-簡介 今天玩點新鮮的,使用一個新庫 aiohttp ,利用它提高咱爬蟲的爬取速度。 安裝模塊常規套路 pip install aiohtt...

    z2xy 評論0 收藏0
  • Python爬蟲入門教程 7-100 蜂鳥網圖片爬取之二

    摘要:蜂鳥網圖片簡介今天玩點新鮮的,使用一個新庫,利用它提高咱爬蟲的爬取速度。上下文不在提示,自行搜索相關資料即可創建一個對象,然后用該對象去打開網頁。可以進行多項操作,比如等代碼中等待網頁數據返回創建線程,方法負責安排執行中的任務。 1. 蜂鳥網圖片-簡介 今天玩點新鮮的,使用一個新庫 aiohttp ,利用它提高咱爬蟲的爬取速度。 安裝模塊常規套路 pip install aiohtt...

    hufeng 評論0 收藏0
  • Python爬蟲入門教程 7-100 蜂鳥網圖片爬取之二

    摘要:蜂鳥網圖片簡介今天玩點新鮮的,使用一個新庫,利用它提高咱爬蟲的爬取速度。上下文不在提示,自行搜索相關資料即可創建一個對象,然后用該對象去打開網頁。可以進行多項操作,比如等代碼中等待網頁數據返回創建線程,方法負責安排執行中的任務。 1. 蜂鳥網圖片-簡介 今天玩點新鮮的,使用一個新庫 aiohttp ,利用它提高咱爬蟲的爬取速度。 安裝模塊常規套路 pip install aiohtt...

    mcterry 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<