Python:从事件循环/执行中分离asyncio协同声明

时间:2017-02-11 03:42:49

标签: python python-3.x python-asyncio coroutine

Python版本:3.5.2

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

在我的模型中,最终用户定义了对单个对象进行操作的 async coroutine

如, 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可以分配给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 中实际的eventloop执行之前修改其输入参数的值? 即,相同的函数调用,但具有修改的参数值。
  • 如果那是不可能的,有没有更好的方法来隐藏引擎下的迭代逻辑? (可以使用** kwargs,用户函数名称作为字符串传递)

1 个答案:

答案 0 :(得分:1)

试试这个:

<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">

<div class="fa-icons">

  <span class="fa-stack fa-5x">
    <a href="" target="_blank">
      <i class="fa fa-circle fa-stack-2x icon-background-face fa-fw"></i>
      <i class="fa fa-facebook fa-1x fa-stack-1x fa-fw"></i>
    </a>
  </span>
    <span class="fa-stack fa-5x">
    <a href="" target="_blank">
      <i class="fa fa-circle fa-stack-2x icon-background-twit fa-fw"></i>
      <i class="fa fa-twitter fa-1x fa-stack-1x fa-fw"></i>
    </a>
  </span>
  <span class="fa-stack fa-5x">
    <a href="" target="_blank">
      <i class="fa fa-circle fa-stack-2x icon-background-tube"></i>
      <i class="fa fa-youtube fa-1x fa-stack-1x"></i>
    </a>
  </span>
  <span class="fa-stack fa-5x">
    <a href="">
      <i class="fa fa-circle fa-stack-2x icon-background-env"></i>
      <i class="fa fa-envelope fa-1x fa-stack-1x"></i>
    </a>
  </span>
</div>

用法:

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