乙個有趣的小例子,帶你入門協程模組 asyncio

2021-09-27 13:38:53 字數 3380 閱讀 7758

上篇文章寫了關於yield from的用法,簡單的了解非同步模式,【這次讓我們通過乙個有趣例子帶大家了解asyncio基本使用。

1.通過不停的依次順序迭代"|/-"中的乙個字元。

2.每次輸出前使用退格符模擬乙個動態效果。所謂的退格符就是刪除上乙個字串,並在原來的位置輸出新的字串。

**實現:

1 import  itertools

2 import sys

3 import time

4 flush=sys.stdout.flush

5 for i in itertools.cycle("|/-\\"):

6 print('\b'*len(i)+i,end='')

7 flush()

8 time.sleep(.1)

**解釋

1,2,3行匯入需要的包。

4行定義7行呼叫,強制重新整理快取。

當我們列印一些字元時,並不是呼叫print函式後就立即列印的。

一般會先將字元送到緩衝區,然後再列印。這就存在乙個問題,

如果你想等時間間隔的列印一些字元,

但由於緩衝區沒滿,不會列印。就需要採取強制重新整理等手段了。

5行,使用itertools.cycle無窮的迭代括號內的字串。

6行,print預設是print(end='\n'),這裡修改其預設方法end='',不換行。

關鍵作用的是'\b','\b'*len(i)表示多次退格,長度由迭代的字元的個數決定。

8行 模擬休眠0.1秒。

這裡只是乙個簡單的效果演示,下面我們使用乙個使用協程的例子。

該例子參考流暢的python,我對其作了部分修改。先看**,後面再做解釋。

# -*- coding: utf-8 -*-

# @time : 2018/12/19 9:08 pm

# @author : cxa

# @file : 18-2.py

# @software: pycharm

# 通過協程以動畫形式顯示文字式旋轉指標

import asyncio

import itertools

import sys

import time

async def spin(msg): # (1)

write, flush = sys.stdout.write, sys.stdout.flush # (2)

for char in itertools.cycle('|/-\\'): #(3)

status = char + ' ' + msg

print(status, end='')

flush() #(4)

# write('\b' * len(status)) # (5)

print('\b' * len(status), end='') # (6)

try:

await asyncio.sleep(.1) # (7)

except asyncio.cancellederror: # (8)

break

# write(" " * len(status) + '\b' * len(status)) # (9)

print(" " * len(status) + '\b' * len(status), end='') # (10)

async def slow_function():

# 假裝等待io一段時間

await asyncio.sleep(3)

return "very good!"

async def supervisor():

# loop = asyncio.get_event_loop() # (11)

# spinner = loop.create_task(spin('thking!')) # (12)

spinner = asyncio.ensure_future(spin('thking!')) # (13)

print('spinner object:', spinner) # (14)

result = await slow_function() # (15)

spinner.cancel() # (16)

return result

def main():

loop = asyncio.get_event_loop() # (17)

result = loop.run_until_complete(supervisor()) # (18)

loop.close()# (19)

print("result:", result)

if __name__ == '__main__':

main()

下面對上面編號進行一一講解。

首先匯入必須的包,其中asyncio就是我們要使用的協程包。

(1)def代表乙個函式或者方法,如果在前面加async def這個就變成協程了。不再是乙個方法。

在python3.4的時候通過使用@asyncio.coroutine來修飾乙個函式使其變為乙個協程。現在不推薦使用。

(2) 定義物件方便後面使用。

(3)itertools.cycle會把乙個可迭代物件無限重複下去。

(4)強制重新整理快取

(5)(6)這兩個是等價的:

當我們在使用print的時候,實際上是呼叫了 sys.stdout.write(obj+'\n'),print在列印時會自動加個換行符。

這裡就是一開始說的使用指定字串長度的退格符

(7)我們使用asyncio.sleep函式來模擬io操作。

(8)執行(16)的時候觸發。

(9)(10)這兩個是等價的,輸出最後的顯示結果。

(11)(12)這兩句可以用(13)來替代使用asyncio.ensure_future(coroutine)

和 loop.create_task(coroutine)都可以建立乙個task。

(14) 輸出的是乙個協程物件

(15)使用await把控制權交給主迴圈,以便loop呼叫其他的協程。

(16)task物件可以取消,取消後會在協程當前暫停的yield處丟擲asyncio.cancellederror異常。

(17)(18) asyncio.get_event_loop方法可以建立乙個事件迴圈,

然後使用run_until_complete將協程註冊到事件迴圈,並啟動事件迴圈。協程的返回值是這次呼叫的返回值。

(19)結束迴圈。

文字的乙個小例子

自然語言文字預處理 導入庫 import pandas as pd import jieba 結巴分詞 from sklearn.feature extraction.text import tfidfvectorizer 基於tf idf的詞頻轉向量庫 分詞函式 def jieba cut str...

ViewPager的乙個小例子

早就聽說有這個viewpager控制項,專案要中使用的也多,viewpager也是更新到了viewpager2。但是我一直沒有使用過,現在記錄一下簡單的使用方法。它的使用和recycleview listview的使用大同小異。也需要介面卡和監聽事件。相信用過這些控制項的同學一定不陌生。上 acti...

實現乙個有趣的小效果

一 新建乙個project。二 新增兩個textview,並設定它的屬性。android id id tv one android layout width wrap content android layout height wrap content android text 瘋狂源自夢想,技術成...