处理存储在字典中的已解析变量

时间:2015-07-14 12:37:49

标签: python eval pyparsing

是否有更好,更pythonic的方法来解析并将值设置为变量(存储在var_dict字典中)并从中获取值?

以下代码完全正常,但特别是设置和获取部件看起来太复杂了。

from pyparsing import Word, nums, Forward, ZeroOrMore, alphas, alphanums, Group, Combine

def test_grammar():
    number  = Word(nums)
    itemlist = Forward()
    items = (number | itemlist)
    itemlist << ('[' + items + ZeroOrMore(',' + items) + ']')
    variable = Word(alphas, alphanums+"_")("variable")
    data = itemlist("data")
    assignment = Group(variable + '=' + data)("assignment")
    indexes  = ZeroOrMore('[' + number + ']')("index")
    query    = Combine(variable + indexes)("query")
    action   = assignment | query
    return action

var_dict = {}

test_input1 = "nl = [1, [2, 3]]"
test_input2 = "nl[1][1]"

tokens1 = test_grammar().parseString(test_input1)
variable = tokens1['assignment']['variable']
data = ''.join(tokens1['assignment']['data'])
var_dict[variable] = eval(data)
print var_dict['nl']

tokens2 = test_grammar().parseString(test_input2)
variable = tokens2['query']['variable']
index = ''.join(tokens2['query']['index'])
print eval("var_dict['" + variable + "']" + index)

根据需要制作:

[1, [2, 3]]
3

1 个答案:

答案 0 :(得分:2)

eval()通常是获取有时危险的快捷方式的标志,而不是使用语言本身来表达解决方案。出于懒惰或缺乏对语言的了解。可以避免两个eval()次呼叫。

第一个用于解析可以通过pyparsings解析操作解决的数字列表。

第二个就是避免一个简单的循环。

from pyparsing import (
    Word, nums, Forward, ZeroOrMore, alphas, alphanums, Group, Combine, Suppress
)


def test_grammar():
    number = Word(nums).setParseAction(lambda toks: int(toks[0]))
    itemlist = Forward()
    items = number | itemlist
    itemlist << Group(
        Suppress('[')
        + items
        + ZeroOrMore(Suppress(',') + items)
        + Suppress(']')
    ).setParseAction(lambda toks: list(toks))
    variable = Word(alphas, alphanums + '_')('variable')
    data = itemlist('data')
    assignment = Group(variable + '=' + data)('assignment')
    indexes = ZeroOrMore(Suppress('[') + number + Suppress(']'))('indexes')
    query = Combine(variable + indexes)('query')
    action = assignment | query
    return action


def main():
    variables = dict()

    test_input_a = 'nl = [1, [2, 3]]'
    test_input_b = 'nl[1][1]'

    grammar = test_grammar()
    tokens = grammar.parseString(test_input_a)
    data = tokens['assignment']['data'][0]
    variables[tokens['assignment']['variable']] = data
    print variables['nl']

    tokens = grammar.parseString(test_input_b)
    data = variables[tokens['query']['variable']]
    for index in tokens['query']['indexes']:
        data = data[index]
    print data


if __name__ == '__main__':
    main()