在 python 中重复将异步函数的 return 值返回给自身

Repeatedly hand the return value of an async function, back to itself, in python

def initial_number_adder(first_number_ever):
    # takes an integer from user and adds 1
    added_number = first_number_ever + 1
    return added_number


async def repeated_number_adder(old_result):
    while 1:
        await asyncio.sleep(0.5)
        if datetime.utcnow().second == 0 or datetime.utcnow().second == 30:
            # takes the integer from the initial fxn, initially.

            # takes the return value from itself on the 0th and 30th second of 
            # every minute, from then on.

            # adds 1 as well.

            new_result = old_result + 1
            print(new_result)
            return await new_result


async def other_cool_fxn():
    print('extra function to make things more complex')
    await asyncio.sleep(1)


async def main():
    first_time = 0
    # first result comes from user input. for example '1'
    if first_time == 0:
        first_result = initial_number_adder(1)
        first_time = 1
        second_result = await asyncio."""wait or gather?"""([repeated_number_adder(first_result)])
    else:
        # for all results after the first (and the second in this case. I'm hoping to clean this up and only run repeated_number_adder in the loop below.
        all_subsequent_results = await asyncio."""wait/gather"""([repeated_number_adder("""result of return of repeated_number_adder"""),other_cool_fxn()])
        # want something like a future here   



loop = asyncio.get_event_loop() 
loop.run_forever(main())

我希望 运行 初始(同步)函数 (initial_number_adder),将其 return 传递给第二个异步函数 (repeated_number_adder),然后 运行 该函数在循环中运行,将其先前的 return 值永远传递回自身。

如果我可以使两个函数异步,并从任务列表中管理第一个函数的单个首字母 运行,那也很棒。这只是我能想到的最好的开始方式(初始同步传递到异步循环)

我将使用像这样的设置和 aiohttp 来发出 GET 请求。一个函数 return 最初是一个大的 DataFrame,第二个函数将异步附加一个新行并每 15 分钟进行一次计算,然后将 DataFrame 和计算传递回自身。 (只是想为任何好奇的人提供一个要点)

我感谢你的时间。如果有任何需要澄清的地方,请告诉我。

题目中的伪代码有几个问题。

  • run_forever() 不接受协程;它不接受任何参数并且运行永远事件循环(或直到调用loop.stop())。要永远 运行 协程,只需在其主体中使用 while True 循环,并在调用 run_forever().

  • 之前将其添加到循环中
  • await new_result 将不起作用,因为 new_result 是一个整数。 await 的有效参数是 awaitable objects,例如协程和期货。如果结果准备就绪,则使用常规 return 语句从协程 return 它完全没问题。

  • 您不需要 gatherwait 等待单个协程,如 repeated_number_adder 的第一次调用,您可以 [=17= 】 直接。您需要 gather 等待多个协程的结果 运行 并行。

考虑到这些,您可以编写如下程序:

import asyncio
from datetime import datetime

def initial_number_adder(first_number_ever):
    # takes an integer from user and adds 1
    added_number = first_number_ever + 1
    return added_number

async def repeated_number_adder(old_result):
    while True:
        await asyncio.sleep(0.5)
        if datetime.utcnow().second == 0 or datetime.utcnow().second == 30:
            return old_result + 1

async def other_cool_fxn():
    print('extra function to make things more complex')
    await asyncio.sleep(1)

async def main():
    next_number = initial_number_adder(1)
    while True:
        next_number, _cool_result = await asyncio.gather(
            repeated_number_adder(next_number), other_cool_fxn())
        print('got', next_number)

loop = asyncio.get_event_loop()
# or simply loop.run_until_complete(main()), which will never complete
loop.create_task(main())
loop.run_forever()