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)
我的问题是:
- 是否可以维护对声明的协程对象的引用
在另一个文件 (user.py) 中并在 my_api.py 内部实际事件循环执行之前修改其输入参数的值?
即,相同的函数调用,但修改了参数值。
- 如果那不可能,是否有更好的方法来隐藏引擎盖下的迭代逻辑?
(可以使用 **kwargs 并将用户函数名称作为字符串传递)
试试这个:
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)
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)
我的问题是:
- 是否可以维护对声明的协程对象的引用 在另一个文件 (user.py) 中并在 my_api.py 内部实际事件循环执行之前修改其输入参数的值? 即,相同的函数调用,但修改了参数值。
- 如果那不可能,是否有更好的方法来隐藏引擎盖下的迭代逻辑? (可以使用 **kwargs 并将用户函数名称作为字符串传递)
试试这个:
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)