从字典中评估表达式

时间:2015-01-06 15:55:12

标签: python list python-2.7 dictionary

我正在尝试构建与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,我该怎么做?

0 个答案:

没有答案