class sheet:
def __init__(self):
def close_game():
print("game closed")
def click():
eval("close_game()")
click()
s1 = sheet()
I'm getting such error:
File "<string>", line 6, in click
NameError: name 'close_game' is not defined
But if I replace 'eval("close_game()")' with 'close_game()' it works correctly. Please explain to me why it works like that.
CodePudding user response:
eval
does not have access to the scope chain. It can only see immediate local variables by default:
def outer():
non_loc = 1
def inner_var():
print(non_loc)
def inner_eval():
print(eval('non_loc'))
inner_var() # ok
inner_eval() # not ok
outer()
You can, however, pass whatever you want in the locals
argument.
CodePudding user response:
The reason is that eval
sets up its own namespace and close_game
is not present in that namespace by default. You can add it explicitly like this:
...
def close_game():
print("game closed")
def click():
eval("close_game()", {"close_game": close_game})
Then it will resolve properly and the function will be called as expected.
PS: I suppose it is prudent to mention that using eval
is usually risky business. Just in case you are not aware, it is easy to introduce huge security vulnerabilities. This has been discussed on this platform extensively, so I am just going to leave this warning.