Python: Eval, дающий NameError в функции - PullRequest
0 голосов
/ 13 февраля 2019

Я хочу использовать eval для выполнения операций, чтобы определить, равны ли a и b 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 голосов
/ 13 февраля 2019

Проблема в этом случае eval попытаться найти a и b в глобальной области видимости, а не в функции scop (это означает, что a и b просто допустимы в функциональном блоке).так что вы можете передать текущую область действия функции, используя 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

Тогда ваш код будет работать.

для лучшего понимания попробуйте определить a иb в глобальной области видимости, вы можете увидеть, как она работает, например:

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: используя отформатированные строки, он получает текущие a и b и передает их в eval как то, что у них внутри, например:

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

Также вы можете использовать any () вместо len() >= 1

...