簡體   English   中英

python中如何實現async方法

[英]How to implement async method in python

我想在下面的代碼中實現異步方法:

import time

def main(num):
    num_list = []
    for i in range(num):
        num_list.append(i)
        print("The number that is added in list is:", i)
        time.sleep(2)
    return num_list


def count():
    start_time = time.time()
    num_list = [3,5,2,8,2]
    for i in num_list:
        print("\nIn count() = ", i)
        data = main(i)
        print("Got data from main() = ", data)
        time.sleep(2)
    total_time = time.time() - start_time
    print("The code took",total_time,"seconds to complete")

if __name__ == "__main__":
    count()

此代碼需要 50 秒才能完成。 我試圖在此代碼中實現異步方法,但未能成功,因為我才剛剛開始學習它。 你能告訴我如何在這段代碼中實現異步方法嗎?

這是我嘗試實現異步方法的代碼:

import asyncio, time
from asgiref.sync import sync_to_async

@sync_to_async
def main(num):
    num_list = []
    for i in range(num):
        num_list.append(i)
        print("The number that is added in list is:", i)
        time.sleep(2)
    return num_list

def get_data(data_var):
    try:
        data_var.send(None)
    except StopIteration as e:
        return e.value


async def count():
    start_time = time.time()
    num_list = [3,5,2,8,2]
    for i in num_list:
        print("In count() :".format(i))
        task1 = asyncio.ensure_future(main(i))
        data = get_data(main(i))
        print("In main() = {}".format(data))
        await asyncio.sleep(2)
        await task1
    total_time = time.time() - start_time
    print("The code took",total_time, "seconds to complete")

if __name__ == "__main__":
    asyncio.run(count())

我沒有得到 num_list 作為返回值,而是得到了 None。

如果你能把你的main轉成async function,那么就可以這樣寫了。

import asyncio
import time
from loguru import logger


async def main(num):
    num_list = []
    for i in range(num):
        num_list.append(i)
        logger.info(f"The number that is added in list is: {i}")
        await asyncio.sleep(2)
    return num_list


async def count():
    start_time = time.time()
    num_list = [3,5,2,8,2]
    task_list = []
    for i in num_list:
        logger.info(f"In count() = {i}")
        task = asyncio.create_task(main(i))
        task_list.append(task)
    result_list = await asyncio.gather(*task_list)
    for r in result_list:
        logger.info(f"Got data from main() = {r}")
    total_time = time.time() - start_time
    logger.info(f"The code took {total_time} seconds to complete")

loop = asyncio.get_event_loop()
loop.run_until_complete(count())

如果你不能轉換主要的 function,線程是你最好的選擇。

from concurrent.futures import ThreadPoolExecutor, as_completed
from loguru import logger

def main(num):
    num_list = []
    for i in range(num):
        num_list.append(i)
        logger.info(f"The number that is added in list is: {i}")
        time.sleep(2)
    return num_list


def count():
    start_time = time.time()
    num_list = [3,5,2,8,2]
    with ThreadPoolExecutor(max_workers=5) as executor:
        futures = {}
        for k in num_list:
            logger.info(f"In count() = {k}")
            futures[executor.submit(main, k)] = k
        for future in as_completed(futures):
            logger.info(f"Got data from main() = {future.result()}")
            time.sleep(2)
        total_time = time.time() - start_time
        logger.info(f"The code took {total_time} seconds to complete")

count()

兩者都將在整體執行時間方面實現相同的目標。

那真的不是做異步編程的方法,看看這篇文章

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM