2017-02-11 59 views
0

Python版本:3.5.2的Python:从事件中分离ASYNCIO协同程序申报循环/执行

我想实现一个简单的使用ASYNCIO为我的最终用户使用的界面。

在我的模型中,最终用户限定异步协程奇异对象(一个或多个)上操作。

例如, 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 

PS:addr_object和property_object可以分配给在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) 

我的问题是:

  • 是否有可能保持参照对象的协程声明在另一个文件(user.py) 和实际事件循环执行之前修改my_api.py内它的输入参数值? 即相同的函数调用,但具有修改的参数值。
  • 如果这是不可能的,有没有更好的方法来隐藏引擎盖下的迭代逻辑? (可以使用**与用户函数名kwargs作为字符串传递)

回答

1

试试这个:

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) 
+0

谢谢!看到一个比我原来的问题短几行的工作解决方案是一种很棒的感觉。 :) 还有一个问题: 如果user_funcs有一个** kwargs作为第三个位置参数,那么如何维护它的上下文呢? (不需要操作,但需要在batch_runner(...)期间传入)。 – Slakker

+0

'func(* args,** kwargs)'? – Udi