如何在exec或eval中使用无效的变量名?

时间:2017-08-15 02:53:53

标签: python exec eval

我想用字典中的变量计算公式。例如:

d = {'a': 1}
exec('b=a+1', globals(), d) # d => { 'a': 1, 'b': 2 }

由于字典的数据源来自Python之外(例如,Json / Yaml),因此字典的键名可能无效,因为Python的变量名称。所以下面的代码:

d = {':a': 1}
exec('b=:a+1', globals(), d) # expected d => { ':a': 1, 'b': 2}

抛出错误:

File "<string>", line 1
b=:a
  ^
SyntaxError: invalid syntax

您是否有任何想法在exec或eval中使用无效变量?

2 个答案:

答案 0 :(得分:0)

[替换基础方法]

这个怎么样?我确认这个工作正常。

但是这不能处理新的无效变量分配,如“:b =:a + 1”。

d = {':a': 1}
expression = 'b=:a+1'

def exec2(expression, d):

    d2 = {}
    keymap={}
    for idx, (k, v) in enumerate(d.items()):
        k2 = "_" + str(idx)
        d2[k2] = v
        keymap[k2] = k

        expression = expression.replace(k, k2)

    # d2 => {'_0': 1}
    # expression => b=_0+1

    exec(expression, globals(), d2)

    for k2, v in d2.items():
        if k2 in keymap:
            k = keymap[k2]
            d[k] = v
        else:
            d[k2] = v
    # d => {':a': 1, 'b': 2}
    return d

答案 1 :(得分:0)

[在表达式中使用d [k]的朴素方法]

如果我们可以强制使用表达式中的'd [k]'给作者,那么我们可以无需替换即可处理。

这种方法也可以处理新的无效变量分配,如“:b =:a + 1”。

但是在这种方法中,作者必须意识到这种逃避格式...

def exec3(expression, d):
    exec(expression, globals(), d)
    return d

d = {':a': 1}
expression = 'b= d[":a"] + 1'
exec3(expression, d) # d => {':a': 1, 'b': 2}

d = {':a': 1}
expression = 'd[":b"] = d[":a"] + 1'
exec3(expression, d) # d => {':a': 1, ':b': 2}