亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

api請求的初學者異步/等待問題

api請求的初學者異步/等待問題

慕俠2389804 2023-05-23 10:48:13
我想加快一些 API 請求...為此,我試圖弄清楚如何做并復制一些運行的代碼,但是當我嘗試自己的代碼時,它不再是異步的。也許有人發現失???復制代碼(從計算器中猜測):#!/usr/bin/env python3import [email protected] func_normal():    print('A')    yield from asyncio.sleep(5)    print('B')    return 'saad'@asyncio.coroutinedef func_infinite():    for i in range(10):        print("--%d" % i)    return 'saad2'loop = asyncio.get_event_loop()tasks = func_normal(), func_infinite()a, b = loop.run_until_complete(asyncio.gather(*tasks))print("func_normal()={a}, func_infinite()=".format(**vars()))loop.close()我的“自己的”代碼(最后我需要返回一個列表并合并所有函數的結果):import asyncioimport [email protected] say_after(start,count,say,yep=True):    retl = []    if yep:        time.sleep(5)    for x in range(start,count):        retl.append(x)        print(say)    return retldef main():    print(f"started at {time.strftime('%X')}")            loop = asyncio.get_event_loop()    tasks = say_after(10,20,"a"), say_after(20,30,"b",False)    a, b = loop.run_until_complete(asyncio.gather(*tasks))    print("func_normal()={a}, func_infinite()=".format(**vars()))    loop.close()    c =  a + b    #print(c)    print(f"finished at {time.strftime('%X')}")main()或者我完全錯了,應該用多線程解決這個問題?對于返回我需要合并的列表的 API 請求,最好的方法是什么?
查看完整描述

1 回答

?
慕虎7371278

TA貢獻1802條經驗 獲得超4個贊

為每個需要改進的部分添加了評論。刪除了一些簡單的代碼。


事實上,我沒有發現 using range()wrapped in coroutine 和使用async def, 可能值得更重的操作有任何性能提升。


import asyncio

import time


# @asyncio.coroutine IS DEPRECATED since python 3.8

@asyncio.coroutine

def say_after(wait=True):

    result = []


    if wait:

        print("I'm sleeping!")

        time.sleep(5)

        print("'morning!")

        # This BLOCKs thread, but release GIL so other thread can run.

        # But asyncio runs in ONE thread, so this still harms simultaneity.


    # normal for is BLOCKING operation.

    for i in range(5):

        result.append(i)

        print(i, end='')

    print()


    return result



def main():

    start = time.time()


    # Loop argument will be DEPRECATED from python 3.10

    # Make main() as coroutine, then use asyncio.run(main()).

    # It will be in asyncio Event loop, without explicitly passing Loop.

    loop = asyncio.get_event_loop()

    tasks = say_after(), say_after(False)


    # As we will use asyncio.run(main()) from now on, this should be await-ed.

    a, b = loop.run_until_complete(asyncio.gather(*tasks))


    print(f"Took {time.time() - start:5f}")


    loop.close()



main()

更好的方法:


import asyncio

import time



async def say_after(wait=True):

    result = []


    if wait:

        print("I'm sleeping!")

        await asyncio.sleep(2)  # 'await' a coroutine version of it instead.

        print("'morning!")


    # wrap iterator in generator - or coroutine

    async def asynchronous_range(end):

        for _i in range(end):

            yield _i


    # use it with async for

    async for i in asynchronous_range(5):

        result.append(i)

        print(i, end='')

    print()


    return result



async def main():

    start = time.time()


    tasks = say_after(), say_after(False)

    a, b = await asyncio.gather(*tasks)


    print(f"Took {time.time() - start:5f}")



asyncio.run(main())


結果

你的代碼:


DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead

  def say_after(wait=True):

I'm sleeping!

'morning!

01234

01234

Took 5.003802

更好的異步代碼:


I'm sleeping!

01234

'morning!

01234

Took 2.013863

請注意,固定代碼現在在其他任務休眠時完成其工作。


查看完整回答
反對 回復 2023-05-23
  • 1 回答
  • 0 關注
  • 128 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號