我是编程和浏览阅读有关函数和类的一些主题的新手。 因此,在阅读了关于函数和封闭函数之后,我试图通过仅限制函数及其范围来模仿类中的继承搜索。
示例:
代码
def f1():
t=1
def f2(x):
return eval(x)
return f2
为什么在执行
时会出现名称错误 f1()('t') #expecting 1 return
但不是在定义说
时def f1():
t=1
def f2():
return t
return f2
f()() # 1 is returned here
我可以通过在f2范围内将t定义为非本地来解决这个问题,这意味着第一个代码只在f2的本地范围内查找。为什么会这样? `
答案 0 :(得分:1)
这里的问题是eval的背景。默认情况下,eval使用调用它的环境中的locals和globals。如果我们写:
def f1():
t = 1
def f2(x):
return eval(x)
return f2
然后在f2
内,t
未包含在全局变量或本地变量中,因此eval语句将无法访问。如果在t
内实际使用f2
,则Python只会向t
的本地人添加f2
。因此,有些令人惊讶的是,以下代码将正确执行:
def f1():
t = 1
def f2(x):
print(t)
return eval(x)
return f2
因为t
现在在f2
内使用。确保这一点始终有效的更好方法是执行以下操作:
def f1():
t = 1
eval_globals = globals()
eval_locals = locals()
def f2(x):
return eval(x, eval_globals, eval_locals)
return f2
这将覆盖eval的上下文,提供f1
范围内的全局变量和局部变量。
一个警告,因为你提到你是一个新的程序员:一般来说,除非你有充分的理由使用它们,否则你应该避免使用eval语句。有更好的方法来实现你在这里所做的事情,而不需要求助于评估。