Python: Eval 在函数中给出 NameError

Python: Eval giving NameError in function

我想用eval做一些运算,看看ab是否等于cc

我的代码:

def Expression(a, b, c):
    operators = ["+", "-", "*", "/"]
    return len([i for i in operators if eval("a () b".replace("()", i)) == c]) >= 1

Expression(1, 2, 3)

出于某种原因,这会导致 NameError。错误日志:

return len([i for i in operators if eval("a () b".replace("()", i)) == c]) >= 1
  File "<string>", line 1, in <module>
NameError: name 'a' is not defined

因为函数有 a 作为参数,我认为 a 不应该是未定义的。这里有什么问题?

问题是在那种情况下 eval 尝试在全局范围内找到 ab,而不是函数 scop(这意味着 ab 仅在功能块中有效)。因此您可以使用 locals() 将函数当前作用域传递给 eval,如下所示:

def Expression(a, b, c):
    operators = ["+", "-", "*", "/"]
    scope = locals()
    return len([i for i in operators if eval("a () b".replace("()", i), scope) == c]) >= 1

那么你的代码就可以工作了。

为了更好地理解,尝试在全局范围内定义 ab,然后您可以看到它有效,如下所示:

a=1
b=2
def Expression(c):
    operators = ["+", "-", "*", "/"]
    return len([i for i in operators if eval("a () b".replace("()", i)) == c]) >= 1
Expression(3)

此外,您可以通过创建字典将自定义范围传递给 eval 并将其传递给 eval:

scope = {'a':a, 'b':b}

所以,这是你的代码问题。但为了更好的态度,您可以使用@Rakesh 之前所说的,使用格式化字符串,它获取当前的 ab 并将其传递给 eval 作为它们内部的内容,如下所示:

eval(f"{a}{i}{b}") # <Python3.6 
eval("{}{}{}".format(a,i,b)) 

您也可以使用 any() 代替 len() >= 1