1. 程式人生 > 其它 >實驗七 字串 程式設計題 1. 飛來飛去

實驗七 字串 程式設計題 1. 飛來飛去

協程函式定義

協程函式以async開頭

import asyncio
import time
#定義一個協程函式
async def func():
    # time.sleep(5)
    print('AAAAAAAAAAA')

#得到協程物件
res = func()
#建立事件迴圈
loop = asyncio.get_event_loop()
#將協程物件加入到事件迴圈中
loop.run_until_complete(res)
# #python 3.7 可直接使用asyncio.run方法
# asyncio.run(res)

await

'''await + 可等待物件(協程物件,Task物件,IO等待)'''
import asyncio #建立協程函式 async def func(): print('BBBB') response = await func_others() #此處執行等待協程函式執行完畢,並返回值給response,之後繼續往下執行 print('CCCC',response) async def func_others(): print('DDDD') await asyncio.sleep(2) print('EEEE') return 'FFFF' #建立事件迴圈 loop = asyncio.get_event_loop(
) loop.run_until_complete(func())

執行結果:
在這裡插入圖片描述

Future物件

'''Task 繼承Future物件,Task內部await結果處理基於future物件結果
future 有兩種型別,一種是
'''
import asyncio
async def setValue(fut):
    '''延時2秒給fut物件賦值'''
    await asyncio.sleep(2)
    fut.set_result(2)

async def main():
    #獲取當前事件迴圈
    loop = asyncio.get_running_loop(
) #建立一個任務,future物件,並指定函式引數 fut = loop.create_future() #建立任務並將協程物件賦值給任務 await loop.create_task(setValue(fut)) #等待任務最終結果,沒有結果一直等待下去 data = await fut print(data) asyncio.run(main())

concurrent.futures.Tuture

'''
future物件有兩種型別
1、通過事件迴圈建立future物件
2、concurrent.futures.Tuture 物件  ---使用執行緒池或者程序池來實現非同步操作
'''

import time
from concurrent.futures import Future
from concurrent.futures.thread import ThreadPoolExecutor
from concurrent.futures.process import ProcessPoolExecutor

#定普通函式
def func(value):
    time.sleep(2)
    print(value)

if __name__ == '__main__':
    #建立一個執行緒數為5執行緒池
    pool = ThreadPoolExecutor(max_workers=5)
    for i in range(10):
        fut = pool.submit(func,1) #通過執行緒池的方式返回future
        print(fut)

task

'''task:在事件迴圈中新增多個任務'''
import asyncio
import time

async def func():
    print(1)
    #執行緒等待
    await asyncio.sleep(9)
    print(2)
    return 3

async def main():
    print('---START---')
    #建立task任務列表
    task_list = [
        asyncio.create_task(func(),name='test_01'),
        asyncio.create_task(func(),name='test_02')
    ]
    print('---END---')
    done,pending = await asyncio.wait(task_list,timeout=None)
    print(done)
asyncio.run(main())  #python3.7寫法

列印結果:
在這裡插入圖片描述
task優化寫法

    task_list = [
        #直接在此處建立協程物件
        func(),
        func()
    ]
    done,pending = asyncio.run(asyncio.wait(task_list))
    print(done)

兩種不同型別的future結合使用,在不支援非同步的模組中使用非同步程式設計(常用)

'''協程非同步 + requests(不支援)場景(協程函式中呼叫普通函式)'''
import time
import asyncio
import requests
import concurrent.futures

def func():
    #某個耗時操作
    time.sleep(2)
    return 2

async def main():
    loop = asyncio.get_running_loop()
    #第一步:內部會先呼叫 ThreadPoolExecutor的submit方法去申請一個執行緒執行func函式,並返回一個concurrent.futures.Future物件
    #第二部:呼叫asyncio.wrap_futures.future方法將concurrent.future.Future物件包裝成為asyncio.future物件
    #因為concurrent.future.Future物件不支援await方法,所以需要包裝
    fut = loop.run_in_executor(None,func)
    result = await fut
    print('default thread pool',result)

#案例
async def dowmload_images(url):
    print('開始下載:%s'% url)
    #傳送IO請求
    loop = asyncio.get_event_loop()
    #requests模組不支援非同步操作,故使用執行緒池來實現
    future = loop.run_in_executor(None,requests.get,url)
    response = await future
    print('%s:下載完成...',url)
    #本地儲存
    file_name = url.split('_')[-1]
    with open(file_name,'wb') as f:
        f.write(response.content)



if __name__ == '__main__':
    # asyncio.run(main())
    url_list = ['https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1608562578327&di=3a5b6a9e81dbfffeb9591331b98f1364&imgtype=0&src=http%3A%2F%2Fpic.jj20.com%2Fup%2Fallimg%2F1113%2F041620103S8%2F200416103S8-4-1200.jpg',
                'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1608562578327&di=3a5b6a9e81dbfffeb9591331b98f1364&imgtype=0&src=http%3A%2F%2Fpic.jj20.com%2Fup%2Fallimg%2F1113%2F041620103S8%2F200416103S8-4-1200.jpg',
                'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1608562578327&di=3a5b6a9e81dbfffeb9591331b98f1364&imgtype=0&src=http%3A%2F%2Fpic.jj20.com%2Fup%2Fallimg%2F1113%2F041620103S8%2F200416103S8-4-1200.jpg'
                ]
    #建立協程
    tasks = [dowmload_images(url) for url in url_list]
    loop = asyncio.get_event_loop()
    loop.run_until_complete(asyncio.wait(tasks))