仅在访问时执行未来



我想做如下事情:

import asyncio
async def g():
    print('called g')
    return 'somevalue'
async def f():
    x = g()
loop = asyncio.get_event_loop()
loop.run_until_complete(f())
loop.close()

没有输出的地方。请注意,我没有await g()。这将产生一个g was not awaited异常,但我正在寻找g绝对没有运行的行为。

这对我来说很有用,因为我有一个长时间运行的操作和复杂的设置,但我只需要在某些情况下它的结果,所以为什么要在不需要的时候运行它。有点像"按需"的情况。

我该怎么做?

一种选择是使用简单的标志来指示任务:

import asyncio
import random

async def g(info):
    print('> called g')
    if not info['skip']:
        print('* running g', info['id'])
        await asyncio.sleep(random.uniform(1, 3))
    else:
        print('- skiping g', info['id'])
    print('< done g', info['id'])
    return info['id']

async def main():
    data = [{
                'id': i,
                'skip': False
            } for i in range(10)]
    # schedule 10 tasks to run later
    tasks = [asyncio.ensure_future(g(info)) for info in data]
    # tell some tasks to skip processing
    data[2]['skip'] = True
    data[5]['skip'] = True
    data[6]['skip'] = True
    # wait for all results
    results = await asyncio.gather(*tasks)
    print(results)
    print("Done!")

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

另一种选择是使用 task.cancel

import asyncio

async def coro(x):
    print('coro', x)
    return x

async def main():
    task1 = asyncio.ensure_future(coro(1))
    task2 = asyncio.ensure_future(coro(2))
    task3 = asyncio.ensure_future(coro(3))
    task2.cancel()
    for task in asyncio.as_completed([task1, task2, task3]):
        try:
            result = await task
            print("success", result)
        except asyncio.CancelledError as e:
            print("cancelled", e)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

最新更新