2017-06-09 68 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語句,除非你有充分的理由使用它們。有沒有更好的方法來實現你在這裏做什麼,而不訴諸於評估。