2017-02-11 63 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