2012-09-20 32 views
21

我可以把import語句在一個字符串,exec的它,和它的作品(打印隨機數字):在Python中,爲什麼函數中的exec不會導入?

code = """ 
import random 
def f(): 
    print random.randint(0,9) 
""" 

def f(): 
    pass 

exec code 
f() 

現在,如果我把exec codef()在自己的功能和調用它,它不沒有工作。

def test(): 
    exec code 
    f() 

test() 

它說NameError: global name 'random' is not defined。 任何想法發生了什麼? 感謝

+0

好奇心,你爲什麼要這樣做? –

+1

這是壞設計的標誌 - 避免。 –

+0

+ Vincent Savard,我與一款基於Java的產品一起工作,該產品可以讓我在其中編寫Python腳本,並且可以將腳本配置爲在發生某些預定義事件時執行。但是,如果我希望將其函數用作庫,則無法使用標準導入語句來加載另一個腳本。相反,我必須從數據庫和exec()它加載其他腳本的代碼。問題在於,其他腳本導入了我沒有的Java庫,在這種情況下調用庫函數導致+ Alex Varga描述的問題 – Preacher

回答

12

如何:

def test(): 
    exec (code, globals()) 
    f() 
3

指定要在全球random模塊

code = """ 
import random 
def f(): 
    global random 
    print random.randint(0,9) 
""" 

這裏的問題是,你要導入的random模塊到您的功能範圍,而不是全局範圍。

14

這是怎麼回事是該模塊隨機被導入爲測試一個局部變量。試試這個

def test(): 
    exec code 
    print globals() 
    print locals() 
    f() 

將打印

{'code': '\nimport random\ndef f():\n print random.randint(0,9)\n', '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, 'test': <function test at 0x02958BF0>, '__name__': '__main__', '__doc__': None} 
{'random': <module 'random' from 'C:\Python27\lib\random.pyc'>, 'f': <function f at 0x0295A070>} 

f不能看到randomf不是--IF你這樣做的test內嵌套函數的原因:

def test(): 
    import random 
    def f(): 
     print random.randint(0,9) 
    f() 

它會工作。但是,嵌套函數要求外部函數在編譯外部函數時包含內部函數的定義 - 這是因爲您需要設置單元變量來保存兩個(外部和內部)函數之間共享的變量。

要獲得隨機進入全局命名空間,你只想做這樣的事情

exec code in globals(),globals() 

的論點in關鍵字後Exec是在該代碼執行(因而全局和局部的命名空間,在exec'd代碼中定義的名稱被存儲)。

相關問題