我正在尝试构建与magento相同的折扣引擎,只需在python中重写。规则定义由magento应用程序存储在数据库中,条件/操作在php序列化数组中。 在我的数据库中,值存储在php序列化数组中,我已使用phpserialize包成功转换为字典,然后从字典转换为列表以获取表达式部分。
示例字典是这样的(从php序列化数组转换为dict):
{
'type': 'salesrule/rule_condition_combine',
'aggregator': 'all',
'operator': None,
'attribute': None,
'conditions': {0: {
'type': 'salesrule/rule_condition_product_subselect',
'aggregator': 'all',
'operator': '>=',
'attribute': 'qty',
'conditions': {0: {
'operator': '{}',
'attribute': 'category_ids',
'type': 'salesrule/rule_condition_product',
'is_value_processed': False,
'value': '1145',
}},
'is_value_processed': None,
'value': '4',
}},
'is_value_processed': None,
'value': '1',
}
来自上述词典的转换列表:
[['>=', 'qty', '4', 'AND', ['in', 'category_ids', '1145']]]
以上列表是通过这些功能生成的(取自eevee):
def operatorSymbol(self, operator):
if operator == "{}":
return "in"
elif operator == "!{}":
return "not in"
elif operator == "<":
return "<"
elif operator == "<=":
return "<="
elif operator == ">":
return ">"
elif operator == ">=":
return ">="
elif operator == "==":
return "=="
else:
return operator
def aggregatorConvert(self, aggregator):
if aggregator == "any":
return "OR"
else:
return "AND"
def expression_tuple(self, query):
if query.get("attribute"):
exp = []
exp.append(self.operatorSymbol(query.get("operator")))
exp.append(query.get("attribute"))
exp.append(query.get("value"))
return exp
else:
return []
def format_serialized(self, query, counter):
counter = counter or 0
ex = self.expression_tuple(query)
conditions = query.get("conditions")
if conditions:
for i in query.get("conditions"):
if ex:
ex.append(self.aggregatorConvert(query.get("aggregator")))
ex.append(self.format_serialized(query.get("conditions")[i], counter + 1))
return ex
现在,我有几个,很多都有嵌套条件。
我想对dict / list部分进行操作,以便我可以构建一个通用的评估函数,该函数将条件所需的参数计算为true或false。 例如: 上面的List定义:如果category_ids 1145中的产品数量大于等于4,则评估为true。 这是单个表达式,因为List从&gt; =开始并在1145结束。
我该怎么做? 我试过这个:
_operators = {
'<': operator.__lt__,
'<=': operator.__le__,
'>': operator.__gt__,
'>=': operator.__ge__,
'{}': operator.__contains__,
'!{}': lambda x, y: y not in x,
'==': operator.__eq__,
}
def process_condition(self, query):
if query.get('aggregator') == 'any':
agg = any
else:
agg = all
conditions = []
if query['operator']:
op = self._operators[query['operator']]
value = int(query['value'])
attr = query['attribute']
conditions.append(lambda data: op(data[attr], value))
for subquery in query.get('conditions', {}).values():
conditions.append(self.process_condition(subquery))
return lambda data: agg(cond(data) for cond in conditions)
接受dict然后进行评估,如下所示:
cb = process_condition(query)
print(cb(dict(qty=5, category_ids=[1145])))
print(cb(dict(qty=1, category_ids=[240])))
print(cb(dict(qty=5, category_ids=[420])))
分别评估为True,False和False。 但是当dict在键值中有两个category_ids或者更复杂的一个时,它会产生编译错误。 更多样本数据在此要点:Sample Dict and corresponding List as well
哪一个选择做这种评价Dict或List?如果是Dict,我怎样才能克服要点中提到的更复杂的?如果是List,我该怎么做?