Итак, я хочу реализовать фильтр, который проверяет входные данные и соответствует логике, предоставленной в параметре фильтра.
import operator
class InvalidQuery(Exception):
pass
class Filter(object):
binary_operators = {
u"==": operator.eq,
u"<": operator.lt,
u">": operator.gt,
u"<=": operator.le,
u">=": operator.ge,
u"!=": operator.ne,
}
multiple_operators = {
u"or": any,
u"and": all,
}
def __init__(self, tree):
self._eval = self.build_evaluator(tree)
def __call__(self, **kwargs):
return self._eval(kwargs)
def build_evaluator(self, tree):
try:
operator, nodes = list(tree.items())[0]
except Exception:
raise InvalidQuery("Unable to parse tree %s" % tree)
try:
op = self.multiple_operators[operator]
except KeyError:
try:
op = self.binary_operators[operator]
except KeyError:
raise InvalidQuery("Unknown operator %s" % operator)
assert len(nodes) == 2
def _op(values):
return op(values[nodes[0]], nodes[1])
return _op
elements = [self.build_evaluator(node) for node in nodes]
return lambda values: op((e(values) for e in elements))
x = Filter({"and": (
{"==": ("y", "abc")},
{"==": ("y", "qwerty")},
)})
print(x(y='abc', y='qwerty'))
Это работает:
print(x(y='abc'))
Это не:
print(x(y='abc', y='qwerty'))
Я хочу передать логику конструктору и запустить логику на входе, переданном методу. Вход может иметь несколько ключей с одинаковым именем и разными значениями. Пожалуйста помоги. Спасибо