Created
March 28, 2019 06:40
-
-
Save wmalarski/ec8cdb3359f059ed0baccd3f1ac80687 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import inspect | |
class Context: | |
def __init__(self): | |
self._filters = {} | |
self._parsers = {} | |
self._runnable_attr = '_runnable' | |
def filter(self, matching_cls): | |
class FilterCaller: | |
def __init__(selff, filter_cls): | |
selff._filter_cls = filter_cls | |
selff._matching_cls = matching_cls | |
runnable = [func for name, func in inspect.getmembers(filter_cls, inspect.isfunction) | |
if (self._runnable_attr, True) in inspect.getmembers(func)] | |
self._filters[selff] = (filter_cls, matching_cls, runnable) | |
def __call__(selff): | |
return None | |
def __hash__(selff): | |
return hash(str(selff._filter_cls) + str(matching_cls)) | |
def __eq__(selff, other): | |
if isinstance(other, FilterCaller): | |
return selff._filter_cls == other._filter_cls and other._matching_cls == matching_cls | |
return False | |
return FilterCaller | |
def matcher(self, *parsers): | |
def matcher_inner(matcher): | |
self._parsers[matcher] = parsers | |
return matcher | |
return matcher_inner | |
def runnable(self, func): | |
func.__setattr__(self._runnable_attr, True) | |
return func | |
def run(self, filters_call, resource1, resource2): | |
matching_uniq = {} | |
for filter_call_cls in filters_call: | |
matching_cls = self._filters.get(filter_call_cls)[1] | |
if matching_cls is not None: | |
if matching_cls not in matching_uniq: | |
matching = matching_cls() | |
parsers = self._parsers[matching_cls] | |
for parser in parsers: | |
resource1 = parser.parse_resuorce1(resource1) | |
resource2 = parser.parse_resuorce2(resource2) | |
pairs = matching.pairs(resource1, resource2) | |
for parser in parsers: | |
pairs = parser.parse_pairs(resource1, resource2, pairs) | |
matching_uniq[matching_cls] = pairs | |
results = [] | |
for filter_call_cls in filters_call: | |
if filter_call_cls in self._filters: | |
filter_cls, matching_cls, runnable = self._filters[filter_call_cls] | |
pairs = matching_uniq[matching_cls] | |
filter_obj = filter_cls() | |
for run in runnable: | |
result = run(filter_obj, pairs) | |
results.append(result) | |
return results | |
context = Context() | |
class MatcherParser: | |
def parse_pairs(self, resource1, resource2, pairs): | |
return pairs | |
def parse_resuorce1(self, resource1): | |
return resource1 | |
def parse_resuorce2(self, resource2): | |
return resource2 | |
class FirstLastParser(MatcherParser): | |
def parse_pairs(self, resource1, resource2, pairs): | |
return {'a': pairs} | |
class Matching: | |
def pairs(self, resource1, resource2): | |
pass | |
@context.matcher(FirstLastParser()) | |
class ObjectsMatching(Matching): | |
def pairs(self, resource1, resource2): | |
return [] | |
@context.filter(ObjectsMatching) | |
class CyclistsFilter: | |
def __init__(self): | |
print('CyclistsFilter.__init__') | |
@context.runnable | |
def run(self, pairs): | |
print('CyclistsFilter.run', pairs) | |
return [pairs] | |
@context.runnable | |
def run2(self, pairs): | |
print('CyclistsFilter.run2', pairs) | |
return ['dsd', pairs] | |
def main(): | |
results = context.run([CyclistsFilter], 'a', 'b') | |
print(results) | |
# print('a', CyclistsFilter(), type(CyclistsFilter())) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment