2015-07-21 54 views
4

我想在不同的模塊中定義一個lambda函數,它將被執行。在lambda將被調用的模塊中,有方法當lambda被定義時不可用。事實上,當lambda嘗試使用這些函數時,Python會拋出一個錯誤。使用(截至目前)Python中的Lambda函數中的未定義函數

例如,我有兩個模塊。

lambdaSource.py:

def getLambda(): 
    return lambda x: squareMe(x) 

runMe.py

import lambdaSource 

def squareMe(x): 
    return x**2 

if __name__ == '__main__': 
    theLambdaFunc = lambdaSource.getLambda() 
    result  = theLambdaFunc(5) 

如果運行runMe.py,你會得到一個名稱錯誤:NameError: global name 'squareMe' is not defined

我能解決這個問題的唯一途徑在運行時修改lambda的全局變量字典。

theLambdaFunc.func_globals['squareMe'] = squareMe 

這個例子很有意思,但這是我所期望的行爲。任何人都可以解釋爲什麼第一個例子不起作用?爲什麼'squareMe'不適用於lambda函數的範圍?特別是,如果我只是定義了函數squareMe下的lambda,那麼一切正常?

+2

難道你不能讓'getLambda'接受一個參數並傳遞函數,例如'getLambda(f):return lambda x:f(x)'?我看不出爲什麼你需要按照你現在這樣做的方式去做。 – Marius

+0

要清楚,這個例子只是說明了這個問題。實際上,lambda函數來自一個靜態的configuration.ini文件,由另一個python模塊解析,然後傳遞給更高級別的模塊執行。 –

回答

3

您在單獨的模塊中定義了getLambdasquareMelambdaSource模塊只能看到其範圍中定義的內容 - 即,您直接在其中定義的所有內容以及其中的所有內容import

要使用squareMegetLambda,你需要lambdaSource.pyfrom runMe import squareMe聲明(而不是周圍的其他方法,你似乎在做)。

+0

這是有道理的,但我也會認爲,使用解釋性語言,lambda將在執行時具有可用的範圍 –

+0

這與語言的實現方式無關(順便說一句,Python是字節碼 - 編譯,而不是解釋)。這完全是一個設計決定:lambda * does *實際上可以訪問封閉範圍內的所有內容。這只是說範圍是模塊*的範圍(Python除了內置的內容外沒有真正的全局範圍概念)。 –