Python:将异步协程声明与事件分开 looping/execution

Python: Separating asyncio coroutine declaration from event looping/execution

Python版本:3.5.2

我正在尝试使用 asyncIO 为我的最终用户实现一个易于使用的界面。

在我的模型中,最终用户定义了一个 async 协同程序,它对单个对象进行操作。

例如, user_func(addr_object, property_object)

现在,我想做这样的事情...

用户代码:

调用这个文件"user.py"

# instantiating my_api object
batch_runner = my_api.BatchRunner()

# coro_list can have more than one user defined function
coro_list = [user_func(addr_object, property_object)]

# this method takes care of creating the eventloop and running it
batch_runnner.run(coro_list)


# all user defined coroutines live in this file "user.py"
async def user_func(addr_object, property_object):
    ``` operate on the objects
    # await on some operation

P.S.: addr_object和property_object可以赋值给None在user.py 保持 Python 快乐

我的API代码:

#调用这个文件"my_api.py"

class BatchRunner(object):
...
    def run(self, coro_list):
        new_coro_list = list()
        # user can define multiple coroutines, but same type and length of input arguments on all of them
        for coros in coro_list:
            # Say I've 10 different addr_objects for example
            for addr_obj in addr_obj_list:
                # and say another 5 property_objects
                for prop_obj in prop_obj_list:
                    # how to modify coro_list to work on each of these addr_obj and prop_obj?
                    # while maintaining reference to the user defined coroutine in user.py?
                    new_coro_list.append(coros(addr_obj, prop_obj)

        eventloop = asyncio.get_event_loop()
        eventloop.run_until_complete(new_coro_list)

我的问题是:

试试这个:

def get_args():
    for i in range(10):
        for c in "ABCD":
            yield i, c

def batch_runner(funcs):
    tasks = [func(*args) for func in funcs for args in get_args()]
    loop = asyncio.get_event_loop()
    return loop.run_until_complete(asyncio.gather(*tasks))

用法:

async def user_func1(i, c):
    print(">U1", i, c)
    await asyncio.sleep(i / 10)
    print("<U1", i, c)
    return("U1", i, c)    

async def user_func2(i, c):
    print(">U2", i, c)
    await asyncio.sleep(i / 5)
    print("<U2", i, c)
    return("U2", i, c)    

results = batch_runner([user_func1, user_func2])
for result in results:
    print(result)