Python:评估在函数中提供NameError

时间:2019-02-13 12:31:30

标签: python eval nameerror

我想使用eval进行操作,以查看ab是否等于某个运算符的c

我的代码:

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应该是未定义的。这是什么问题?

1 个答案:

答案 0 :(得分:0)

问题在于,在这种情况下,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