2017-06-09 69 views
3

我是新来的编程和脱脂阅读一些功能和类的主题。 因此,在阅读了关于函数和封闭函数之后,我试图通过仅仅调用函数及其范围来模仿类中的继承搜索。围绕功能范围搜索?

例子:

对于代码

def f1(): 
    t=1 
    def f2(x): 
     return eval(x) 
    return f2 

为什么我得到一个名称错误定义说

def f1(): 
    t=1 
    def f2(): 
     return t 
    return f2 
时做

f1()('t') #expecting 1 return

但不是当

f()() # 1 is returned here

我可以通过在f2范围内将t定义为非本地来解决这个问题,这意味着第一个代码仅在f2的本地范围中查找。为什么会发生? `

+2

请缩进您的代码 – ForceBru

+0

[相关](https://stackoverflow.com/questions/44425363/is-it-true-in-python-closure-will-be-stored-if-and-only-if -it-is-mentioned-lex) –

+0

看看https://stackoverflow.com/questions/4020419/why-arent-python-nested-functions-called-closures的接受答案 - 非常好的解释。 – mkiever

回答

1

这里的问题是的上下文。默认情况下,eval使用调用它的环境中的局部变量和全局变量。如果我们写:

def f1(): 
    t = 1 

    def f2(x): 
     return eval(x) 
    return f2 

然后里面f2t不包括在任的全局或当地人,因此将无法进入eval语句。如果在f2内实际使用t,则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语句,除非你有充分的理由使用它们。有没有更好的方法来实现你在这里做什么,而不诉诸于评估。