Welcome, guest | Sign In | My Account | Store | Cart

Alexandre Zani's recipe on function pipelines was useful. I wanted to change it to suit my needs.

Mostly I just wanted to add arbitrary functions and make the pipe line more list like in behavior.

(edit: typos)

Python, 68 lines
 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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
class Pipeline(object):
  def __init__(self, *args):
    if args:
      self._func_list=args
    else:
      self._func_list=[]

  def __call__(self, *args, **kwargs):
    (fargs,fkwargs) = (args,kwargs)
    for f in self:
      results = f(*fargs, **fkwargs)
      if isinstance(results, tuple) and len(results) == 2 and \
              isinstance(results[0],list) and isinstance(results[1],dict):
        fargs,kwargs = results
      else:
        fargs = [results]
        fkwargs = {}
    return results

  def __iter__(self):
    for f in self._func_list:
      yield f
    raise StopIteration

  def __eq__(self, other):
    return self._func_list == other._func_list

  def __add__(self, other):
    funcs = other
    if callable(other):
       funcs = [other] 
    args = list(self._func_list) + list(funcs)
    return Pipeline(*args)

  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(x):
    return x+1

  def mul_2(x):
    return (x * 2)

  def identity(x):
    return x

  p = Pipeline(add_1, mul_2, add_1, mul_2, identity)
  assert(p(1) == 10)
  
  p = p + mul_2
  assert(p(1) == 20)

  q = Pipeline(p, add_1, add_1)
  assert(q(1) == 22)

  r = Pipeline(add_1)
  s = Pipeline(add_1)
  t = r + s

  assert(t(1) == 3)

I wanted something that could do the following:

Pipeline(func1, func2) + Pipeline(func3) to work like one would expect.

Or this:

Pipeline(func1, Pipeline(func3, func4), func2)

And I also just wanted regular functions rather than special functions or needing a decorator on the functions I want to use.

Since I'm iterating through the functions, if the Pipeline throws an exception, it's hard to debug.

Created by Rob L on Sun, 22 May 2011 (MIT)
Python recipes (4591)
Rob L's recipes (1)

Required Modules

  • (none specified)

Other Information and Tasks