aiohttp:response.status 什么时候可用?
aiohttp: when is the response.status available?
aiohttp 入门文档提供了以下客户端示例:
async with aiohttp.ClientSession() as session:
async with session.get('https://api.github.com/events') as resp:
print(resp.status)
print(await resp.text())
我无法理解 response.status
何时可用。我的理解是协程在 await response.read()
行释放控制。我怎么可能在等待响应卷土重来之前访问状态?
resp
对象在 async with
块内可用。因此 resp.status
也可用。您也可以在某些方法上调用 await
,例如 resp.text()
,但不会释放对 async with
块的控制。即使在调用 await
之后,您也可以使用 resp
。
您首先获得 HTTP 响应 headers,其中第一行包含状态代码。如果您这样选择,您可以阅读其余的回复 body(这里有 resp.text()
)。由于 headers 总是相对较小而 body 可能非常大,aiohttp 让您有机会分别阅读两者。
重要区别:await ...
可能会释放对上下文的控制,例如,如果等待的数据不够快。 async with ...
语句也是如此。因此,您的代码在 resp 可用之前不会到达行 print(resp.status)
。
例如代码:
import aiohttp
import asyncio
import urllib.parse
import datetime
async def get(session, url):
print("[{:%M:%S.%f}] getting {} ...".format(datetime.datetime.now(), urllib.parse.urlsplit(url).hostname))
async with session.get(url) as resp:
print("[{:%M:%S.%f}] {}, status: {}".format(datetime.datetime.now(), urllib.parse.urlsplit(url).hostname, resp.status))
doc = await resp.text()
print("[{:%M:%S.%f}] {}, len: {}".format(datetime.datetime.now(), urllib.parse.urlsplit(url).hostname, len(doc)))
async def main():
session = aiohttp.ClientSession()
url = "http://demo.borland.com/Testsite/stadyn_largepagewithimages.html"
f1 = asyncio.ensure_future(get(session, url))
print("[{:%M:%S.%f}] added {} to event loop".format(datetime.datetime.now(), urllib.parse.urlsplit(url).hostname))
url = ""
f2 = asyncio.ensure_future(get(session, url))
print("[{:%M:%S.%f}] added {} to event loop".format(datetime.datetime.now(), urllib.parse.urlsplit(url).hostname))
url = "https://api.github.com/events"
f3 = asyncio.ensure_future(get(session, url))
print("[{:%M:%S.%f}] added {} to event loop".format(datetime.datetime.now(), urllib.parse.urlsplit(url).hostname))
await f1
await f2
await f3
session.close()
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
可以产生这样的结果:
[16:42.415481] added demo.borland.com to event loop
[16:42.415481] added whosebug.com to event loop
[16:42.415481] added api.github.com to event loop
[16:42.415481] getting demo.borland.com ...
[16:42.422481] getting whosebug.com ...
[16:42.682496] getting api.github.com ...
[16:43.002515] demo.borland.com, status: 200
[16:43.510544] whosebug.com, status: 200
[16:43.759558] whosebug.com, len: 110650
[16:43.883565] demo.borland.com, len: 239012
[16:44.089577] api.github.com, status: 200
[16:44.318590] api.github.com, len: 43055
澄清(thx @deceze):在这里您可以看到(查看括号之间的时间)所有协程在发送检索网站的请求后释放控制,并在等待响应文本时第二次释放控制。此外,与 Whosebug 相比,borland 有太多的文本(不包括其他网络特征)以至于它只准备在打印来自 Whosebug 的文本后显示,尽管早些时候被请求。
aiohttp 入门文档提供了以下客户端示例:
async with aiohttp.ClientSession() as session:
async with session.get('https://api.github.com/events') as resp:
print(resp.status)
print(await resp.text())
我无法理解 response.status
何时可用。我的理解是协程在 await response.read()
行释放控制。我怎么可能在等待响应卷土重来之前访问状态?
resp
对象在 async with
块内可用。因此 resp.status
也可用。您也可以在某些方法上调用 await
,例如 resp.text()
,但不会释放对 async with
块的控制。即使在调用 await
之后,您也可以使用 resp
。
您首先获得 HTTP 响应 headers,其中第一行包含状态代码。如果您这样选择,您可以阅读其余的回复 body(这里有 resp.text()
)。由于 headers 总是相对较小而 body 可能非常大,aiohttp 让您有机会分别阅读两者。
重要区别:await ...
可能会释放对上下文的控制,例如,如果等待的数据不够快。 async with ...
语句也是如此。因此,您的代码在 resp 可用之前不会到达行 print(resp.status)
。
例如代码:
import aiohttp
import asyncio
import urllib.parse
import datetime
async def get(session, url):
print("[{:%M:%S.%f}] getting {} ...".format(datetime.datetime.now(), urllib.parse.urlsplit(url).hostname))
async with session.get(url) as resp:
print("[{:%M:%S.%f}] {}, status: {}".format(datetime.datetime.now(), urllib.parse.urlsplit(url).hostname, resp.status))
doc = await resp.text()
print("[{:%M:%S.%f}] {}, len: {}".format(datetime.datetime.now(), urllib.parse.urlsplit(url).hostname, len(doc)))
async def main():
session = aiohttp.ClientSession()
url = "http://demo.borland.com/Testsite/stadyn_largepagewithimages.html"
f1 = asyncio.ensure_future(get(session, url))
print("[{:%M:%S.%f}] added {} to event loop".format(datetime.datetime.now(), urllib.parse.urlsplit(url).hostname))
url = ""
f2 = asyncio.ensure_future(get(session, url))
print("[{:%M:%S.%f}] added {} to event loop".format(datetime.datetime.now(), urllib.parse.urlsplit(url).hostname))
url = "https://api.github.com/events"
f3 = asyncio.ensure_future(get(session, url))
print("[{:%M:%S.%f}] added {} to event loop".format(datetime.datetime.now(), urllib.parse.urlsplit(url).hostname))
await f1
await f2
await f3
session.close()
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
可以产生这样的结果:
[16:42.415481] added demo.borland.com to event loop
[16:42.415481] added whosebug.com to event loop
[16:42.415481] added api.github.com to event loop
[16:42.415481] getting demo.borland.com ...
[16:42.422481] getting whosebug.com ...
[16:42.682496] getting api.github.com ...
[16:43.002515] demo.borland.com, status: 200
[16:43.510544] whosebug.com, status: 200
[16:43.759558] whosebug.com, len: 110650
[16:43.883565] demo.borland.com, len: 239012
[16:44.089577] api.github.com, status: 200
[16:44.318590] api.github.com, len: 43055
澄清(thx @deceze):在这里您可以看到(查看括号之间的时间)所有协程在发送检索网站的请求后释放控制,并在等待响应文本时第二次释放控制。此外,与 Whosebug 相比,borland 有太多的文本(不包括其他网络特征)以至于它只准备在打印来自 Whosebug 的文本后显示,尽管早些时候被请求。