I have a set of filter objects, which inherit the properties of a Filter base class
class Filter():
def __init__(self):
self.filterList = []
def __add__(self,f):
self.filterList += f.filterList
def match(self, entry):
for f in self.filterList:
if not f(entry):
return False
return True
class thisFilter(Filter):
def __init__(self, args):
super().__init__()
....
def thisFilterFunc(entry)->bool:
return True
self.filterList.append(thisFilterFunc)
This filter classes are used by various functions to filter entries
def myfunc(myfilter, arg1, ...):
...
for entry in entries:
if myfilter.match(entry):
... do something
Multiple filters can be added (logical and) by adding instances of these filters:
bigFilter = filter1 + filter2 + ...
This is all comming together quite well, but I would love to generalize this in a way to handle more complex logical constraints, e.g.
bigFilter = (filter1 and filter2) or (filter3 and not filter4)
It feels like this should somehow be possible with overwriting __bool__ of the class instead of using __add__ but the boolean value of the class is only known for a given entry and not during assemly of the filter.
Any ideas how to make this possible? Or is there maybe a more pythonic way do do this?
I would go for something like this:
class Filter:
def __init__(self, filter: Callable[[Any], bool]):
self.filter = filter
def __add__(self, added: Filter):
return OrFilter(self, added)
def __mul__(self, mult: Filter):
return AndFilter(self, mult)
def __invert__(self):
return Filter(lambda x: not self.filter(x))
def __call__(self, entry):
return self.filter(entry)
class AndFilter(Filter):
def __init__(self, left: Filter, right: Filter):
self.left = left
self.right = right
def __call__(self, entry):
return self.left(entry) and self.right(entry)
class OrFilter(Filter):
def __init__(self, left: Filter, right: Filter):
self.left = left
self.right = right
def __call__(self, entry):
return self.left(entry) or self.right(entry)
Then you can create filters, and use them as (filterA + ~filterB) * filterC
You'll probably want to replace that Any with a generic type, so that your filter knows what it's dealing with.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With