Pipelines can be used to chain a series of functions to process a piece of data. For instance you can build a pipeline to process web requests easily including some middleware for instance.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | class Pipeline(object):
def __init__(self, _func_list=None):
if _func_list is None:
_func_list = []
self._func_list = _func_list
def __call__(self, *args, **kwargs):
f = None
while f == None:
try:
f = self.pop(0)
except IndexError:
raise StopIteration()
if callable(f):
return f(self, *args, **kwargs)
else:
f = None
def __iter__(self):
for f in self._func_list:
yield f
def __eq__(self, other):
return self._func_list == other._func_list
def __add__(self, other):
return Pipeline(self._func_list + list(other))
def push(self, f):
return self._func_list.insert(0, f)
def pop(self, *args, **kwargs):
return self._func_list.pop(*args, **kwargs)
def append(self, *args, **kwargs):
return self._func_list.append(*args, **kwargs)
if __name__ == '__main__':
def add_1(pipeline, x):
return pipeline(x + 1)
def mul_2(pipeline, x):
return pipeline(x * 2)
def identity(pipeline, x):
return x
p = Pipeline([add_1, mul_2, add_1, mul_2, identity])
print p(1)
# 10
|
The way this works is: You create the pipeline with: pipeline = Pipeline([f1, f2, f3]). The first pipeline() call will call f1, the second call calls f2, etc...
I use this recipe for WSGI applications. Basically, I create a pipeline including some functions handling authentication, database access, logging, URL dispatching etc. When a request comes in, I copy the pipeline and just call return pipeline(environ, start_response).
More generally, this could be used for just about any event-driven application/framework.