非同步上下文管理器指的是在enter
和exit
方法處能夠暫停執行的上下文管理器。
為了實現這樣的功能,需要加入兩個新的方法:__aenter__
和__aexit__
。這兩個方法都要返回乙個 awaitable型別的值。
非同步上下文管理器的一種使用方法是:
class asynccontextmanager:
async def __aenter__(self):
await log('entering context')
async def __aexit__(self, exc_type, exc, tb):
await log('exiting context')
非同步上下文管理器使用一種新的語法:
async with expr as var:
block
這段**在語義上等同於:
mgr = (expr)
aexit = type(mgr).__aexit__
aenter = type(mgr).__aenter__(mgr)
exc = true
var = await aenter
try:
block
except:
if not await aexit(mgr, *sys.exc_info()):
raise
else:
await aexit(mgr, none, none, none)
和常規的with
表示式一樣,可以在乙個async with
表示式中指定多個上下文管理器。
如果向async with
表示式傳入的上下文管理器中沒有__aenter__
和__aexit__
方法,這將引起乙個錯誤 。如果在async def
函式外面使用async with
,將引起乙個syntaxerror
(語法錯誤)。
使用async with
能夠很容易地實現乙個資料庫事務管理器。
async def commit(session, data):
...async with session.transaction():
...await session.update(data)
...
需要使用鎖的**也很簡單:
async with lock:
...
而不是:
with (yield from lock):
...
python3 非同步模組asyncio
yield方法引入,這裡存在的問題是,如果你想建立從0到1,000,000這樣乙個很大的序列,你不得不建立能容納1,000,000個整數的列表。但是當加入了生成器之後,你可以不用建立完整的序列,你只需要能夠每次儲存乙個整數的記憶體即可。import asyncio asyncio.coroutine...
python3非同步asyncio學習筆記
1 定義 微執行緒,人為創造協程,控制程式上下文切換執行流程,乙個執行緒中只能有乙個協程 2 python實現協程 1 yield yield from 2 asyncio模組 3 gevent模組 版本python3.5以上 1 事件迴圈 asyncio.get event loop 檢測並執行某...
python3 非同步訊息佇列 RQ 處理
rq是redis queue的縮寫,乙個基於redis的簡單 輕量的非同步訊息佇列工具。如果在 中使用者發起乙個用時很久的請求,如果用同步的方式,伺服器就會返回超時。這時候就需要用非同步請求,使用者發起請求後,服務端把作業扔給另乙個程序去執行,然後立刻返回給使用者,使用者再通過輪詢或者其他方式來獲取...