【发布时间】:2016-06-20 11:13:04
【问题描述】:
我正在尝试设计一个可以轻松制作数据处理管道的异步管道。管道由几个功能组成。输入数据从管道的一端进入,从另一端出来。
我想以如下方式设计管道:
- 可以在管道中插入其他函数
- 可以弹出已经在管道中的函数。
这是我想出的:
import asyncio
@asyncio.coroutine
def add(x):
return x + 1
@asyncio.coroutine
def prod(x):
return x * 2
@asyncio.coroutine
def power(x):
return x ** 3
def connect(funcs):
def wrapper(*args, **kwargs):
data_out = yield from funcs[0](*args, **kwargs)
for func in funcs[1:]:
data_out = yield from func(data_out)
return data_out
return wrapper
pipeline = connect([add, prod, power])
input = 1
output = asyncio.get_event_loop().run_until_complete(pipeline(input))
print(output)
这当然可行,但问题是如果我想在这个管道中添加另一个函数(或从中弹出一个函数),我必须重新分解并重新连接每个函数。
我想知道是否有更好的方案或设计模式来创建这样的管道?
【问题讨论】:
-
我认为标准的做法是重新创建管道,例如
connect([add, prod, somethingelse, power])或connect([add, power])。你有理由不想这样做吗?或者我不明白你的问题? -
我想你明白我的意思了,我不想重新创建整个东西,因为如果管道包含几十个功能,当你只需要更改一小部分时重新创建所有东西并不优雅,而且我需要经常更改一些功能,重新创建一切变得乏味和低效。
-
您似乎可以创建一个 Pipeline 类并使用您的函数列表维护一个实例 var,然后实现从该列表中获取/删除函数的方法。然后只需实现
__call__以便可以将 Pipeline 的实例发送到 asyncio 事件循环。 -
@EricConner 我不完全理解您的建议,按照您的建议,我认为问题在于如何实现获取/删除功能?我是否必须重新连接每个功能才能更改一个功能?
-
您能否将您的函数存储在列表中,然后让您的管道引用这些列表?比如
L1 = [add, prod, power],pipeline1 = connect(L1)pipeline2 = connect(L1 + [power])pipeline3 = connect([x for x in L1 if x != add])
标签: python python-3.x asynchronous python-asyncio python-decorators