2012-11-19 73 views
11

可正常工作爲什麼我不能在函數中使用`import *`?

def outer_func(): 
    from time import * 

    print time() 

outer_func() 

我可以在上下文精細定義嵌套函數和其他嵌套函數調用它們:

def outer_func(): 
    def time(): 
     return '123456' 

    def inner_func(): 
     print time() 

    inner_func() 

outer_func() 

我甚至可以導入單個功能:

def outer_func(): 
    from time import time 

    def inner_func(): 
     print time() 

    inner_func() 

outer_func() 

然而,這拋出SyntaxError: import * is not allowed in function 'outer_func' because it contains a nested function with free variables

def outer_func(): 
    from time import * 

    def inner_func(): 
     print time() 

    inner_func() 

outer_func() 

我知道這不是最佳實踐,但它爲什麼不起作用?

+1

有意思的問題... – mgilson

+0

「這個按預期工作」 - 在哪個python版本中? – georg

+0

@ thg435 Python 2. Python 3更嚴格,拒絕第一個例子'SyntaxError:import *只允許在模塊級別'。我已經添加了python-2.x標籤來澄清。 –

回答

22

編譯器無法知道時間模塊是否導出名爲time的對象。

嵌套函數的自由變量在編譯時綁定到閉包單元。關閉單元本身指向編譯代碼中定義的(本地)變量,而不是全局關係。見python data model;函數通過func_globals屬性引用它們的全局變量,而func_closure屬性保存一系列閉包單元(或None)。

因此,您不能在嵌套作用域中使用動態導入語句。

爲什麼嵌套函數需要閉包單元呢?因爲你需要一個機制來指代局部函數變量當函數本身已經完成:

def foo(spam): 
    def bar(): 
     return spam 
    return bar 

afunc = foo('eggs') 

通過調用foo()我獲得的是指一個範圍變量的嵌套函數,且編譯器需要創造必要的引用解釋器能夠再次檢索該範圍變量。因此,這些細胞以及對它們的限制。

相關問題