2017-04-26 29 views
0

我正在嘗試動態創建2個在字符串中定義的函數。代碼:在Python中動態創建函數 - f(2)無法解析(f1)

def main(): 

    fns = ''' 
    def plus_one(x): 
    return x + 1 


    def plus_two(x): 
    return plus_one(x) + 1 

    ''' 
    exec(fns) 

    result = eval('plus_two(11)') 

    print(result) 

if __name__ == '__main__': 
    main() 

保存這些代碼到一個文件名爲dyn_code.py並運行它給了我下面的錯誤:這裏

python dyn_code.py 
Traceback (most recent call last): 
File "dyn_code.py", line 19, in <module> 
main() 
File "dyn_code.py", line 14, in main 
result = eval('plus_two(11)') 
File "<string>", line 1, in <module> 
File "<string>", line 7, in plus_two 
NameError: name 'plus_one' is not defined 

問題是,plus_one無法裏面plus_two得到解決。

plus_one自己在這裏很好,可以調用正確的結果。

任何人都可以給我一個關於如何將代碼注入到本地命名空間的想法嗎?具體來說,我想創建2個函數,一個引用另一個函數。

我特意用兩execeval最開放的形式,我不知道如何限制他們,等我也已經驗證調用exec後兩個功能都存在於當地的命名空間。

更令人沮喪的是,代碼在解釋器會話中工作正常!也就是說,在將這兩個函數通過exec注入解釋器命名空間之後,plus_two運行沒有任何問題。

理想情況下,我想避免的功能,在功能的情況下,即

def plus_two(x): 
    def plus_one(x): 
     return x + 1 

    return plus_one(x) + 1 

這項技術確實可以工作,但我想2層明確命名的和獨立的功能。

+0

後一種方法對我來說似乎更*更明智。 –

回答

0

你的功能縮進在fns很重要!並且您必須通過globals()映射的可選參數!

def main(): 
    fns = '''def plus_one(x): 
    return x + 1 

def plus_two(x): 
    return plus_one(x) + 1 
    ''' 
    exec(fns,globals()) 
    result = eval('plus_two(11)') 

    print(result) 

if __name__ == '__main__': 
    main() 

輸出:

13 

希望它能幫助!

+0

感謝您的回答。縮進沒有任何作用,我使用globals()運行代碼,它工作正常。 – Sawan

0

您需要在撥打exec()時添加globals()字典。您也可以省略plus_two的eval調用,如下所示:

def main(): 
    exec('def plus_one(x):\n return x + 1\n\ndef plus_two(x): return plus_one(x) + 1', globals()) 
    print(plus_two(11)) 

if __name__ == '__main__': 
    main() 
+0

謝謝,是的,我知道eval,我有它的原因。 – Sawan