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 69 70 71 72 73 74 75 76 77 78 79
|
"""
Classes for implementing `Pipeline`s composed of `Filter`s (intended to be
subclassed).
"""
class Filter:
def __init__(self, **kwargs):
raise Exception("AbstractClass")
def run(self, reader, writer):
for block in reader:
block = self(block)
if block:
writer(block)
def step(self, reader, writer):
block = next(reader)
if not block:
raise StopIteration
block = self(block)
if block:
writer(block)
def __call__(self, block):
raise Exception("AbstractMethod")
class Pipeline(Filter):
def __init__(self, **kwargs):
self.pipeline = []
def __call__(self, block):
for function in self.pipeline:
if not block:
return block
try:
f = function.__call__
except AttributeError:
raise TypeError("'" + function.__class__.__name__ + "' is not callable.")
block = f(block)
return block
def append(self, function):
try:
function.__call__
except AttributeError:
raise TypeError("'" + function.__class__.__name__ + "' is not callable.")
return self.pipeline.append(function)
def remove(self, function):
return self.pipeline.remove(function)
def extend(self, pipeline):
for item in pipeline:
self.append(item)
# Container interface
def __len__(self):
return len(self.pipeline)
def __getitem__(self, key):
return self.pipeline[key]
def __setitem__(self, key, value):
try:
value.__call__
except AttributeError:
raise TypeError("'" + value.__class__.__name__ + "' is not callable.")
return self.pipeline.__setitem__(key, value)
def __delitem__(self, key):
return self.pipeline.__delitem__(key)
def __iter__(self):
return self.pipeline.__iter__()
def __contains__(self, item):
return self.pipeline.__contains__(item)
|