亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python中的asyncio庫-shield函數

發布時間:2020-08-24 14:43:49 來源:億速云 閱讀:538 作者:Leah 欄目:編程語言

Python中的asyncio庫-shield函數?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

shield

asyncio.shield,用它可以屏蔽取消操作。一直到這里,我們還沒有見識過Task的取消。看一個例子:

In : loop = asyncio.get_event_loop()
In : task1 = loop.create_task(a())
In : task2 = loop.create_task(b())
In : task1.cancel()
Out: True
In : await asyncio.gather(task1, task2)
Suspending a
Suspending b
---------------------------------------------------------------------------
CancelledError                            Traceback (most recent call last)
cell_name in async-def-wrapper()
CancelledError:

在上面的例子中,task1被取消了后再用asyncio.gather收集結果,直接拋CancelledError錯誤了。這里有個細節,gather支持return_exceptions參數:

In : await asyncio.gather(task1, task2, return_exceptions=True)
Out: [concurrent.futures._base.CancelledError(), 'B']

可以看到,task2依然會執行完成,但是task1的返回值是一個CancelledError錯誤,也就是任務被取消了。如果一個創建后就不希望被任何情況取消,可以使用asyncio.shield保護任務能順利完成。不過要注意一個陷阱,先看錯誤的寫法:

In : task1 = asyncio.shield(a())
In : task2 = loop.create_task(b())
In : task1.cancel()
Out: True
In : await asyncio.gather(task1, task2, return_exceptions=True)
Suspending a
Suspending b
Resuming b
Out: [concurrent.futures._base.CancelledError(), 'B']

可以看到依然是CancelledError錯誤,且協程a未執行完成,正確的用法是這樣的:

In : task1 = asyncio.shield(a())
In : task2 = loop.create_task(b())
In : ts = asyncio.gather(task1, task2, return_exceptions=True)
In : task1.cancel()
Out: True
In : await ts
Suspending a
Suspending b
Resuming a
Resuming b
Out: [concurrent.futures._base.CancelledError(), 'B']

可以看到雖然結果是一個CancelledError錯誤,但是看輸出能確認協程實際上是執行了的。所以正確步驟是:

先創建 GatheringFuture 對象 ts

取消任務

await ts

asynccontextmanager

如果你了解Python,之前可能聽過或者用過contextmanager ,一個上下文管理器。通過一個計時的例子就理解它的作用:

from contextlib import contextmanager
async def a():
    await asyncio.sleep(3)
    return 'A'
async def b():
    await asyncio.sleep(1)
    return 'B'
async def s1():
    return await asyncio.gather(a(), b())
@contextmanager
def timed(func):
    start = time.perf_counter()
    yield asyncio.run(func())
    print(f'Cost: {time.perf_counter() - start}')

timed函數用了contextmanager裝飾器,把協程的運行結果yield出來,執行結束后還計算了耗時:

In : from contextmanager import *
In : with timed(s1) as rv:
...:     print(f'Result: {rv}')
...:
Result: ['A', 'B']
Cost: 3.0052654459999992

大家先體會一下。在Python 3.7添加了asynccontextmanager,也就是異步版本的contextmanager,適合異步函數的執行,上例可以這么改:

@asynccontextmanager
async def async_timed(func):
    start = time.perf_counter()
    yield await func()
    print(f'Cost: {time.perf_counter() - start}')
async def main():
    async with async_timed(s1) as rv:
        print(f'Result: {rv}')
In : asyncio.run(main())
Result: ['A', 'B']
Cost: 3.00414147500004

async版本的with要用async with,另外要注意yield await func()這句,相當于yield + await func()

PS: contextmanager 和 asynccontextmanager 最好的理解方法是去看源碼注釋

關于Python中的asyncio庫-shield函數問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

莆田市| 彰武县| 临湘市| 永平县| 冷水江市| 克山县| 会泽县| 闽侯县| 新营市| 栖霞市| 犍为县| 霸州市| 南昌县| 临澧县| 桂林市| 蓝田县| 乌苏市| 军事| 乌鲁木齐县| 平塘县| 高要市| 璧山县| 文山县| 项城市| 合肥市| 阿克苏市| 奉节县| 全南县| 玛纳斯县| 安宁市| 兴隆县| 延长县| 建德市| 瓮安县| 康保县| 天等县| 台南县| 淳安县| 阳谷县| 铁岭市| 永春县|