2013-08-30 57 views
0
def closure(): 
    a = 2 
    def f(): 
     if a < 5: 
      print a 
    return f 

closure()() 

打印2,這對我很有意義,因爲您可以閱讀封閉變量。試圖分配給Python閉包中的某些東西時發生先發制人的異常?

def closure(): 
    a = 2 
    def f(): 
     if a < 5: 
      a += 1 
      print a 
    return f 

closure()() 

結果在File "closure_problems.py", line 4, in f if a < 5: UnboundLocalError: local variable 'a' referenced before assignment

對我來說也是有意義的,因爲我知道你不能分配給閉合變量。但奇怪的是,行號是指if a < 5,而不是似乎應該是實際違規聲明a += 1

def closure(): 
    a = 2 
    def f(): 
     if a < 5: 
      print a 
      a += 1 
    return f 

closure()() 

結果只在File "closure_problems.py", line 4, in f if a < 5: UnboundLocalError: local variable 'a' referenced before assignment。它甚至不打印2,我完全不明白。

解釋器是否試圖解析塊中的所有內容(未對其進行評估)以查明我是在討論本地的a還是全局的?

回答

2

在函數中分配a使得a成爲f()函數的局部變量。但是在分配之前不能使用它,這就是爲什麼在if a < 5聲明中出現錯誤。

解釋器是否試圖解析塊中的所有內容(無需對其進行評估)以查明我是在討論本地a還是全局的?

是的。或者好吧,沒有嘗試,只有做。

+0

但是'如果一個<5'在第一個例子中是完全正確的。因爲在這種情況下,'a'被解釋爲被關閉的'a',而不是我沒有分配的一些新的局部變量。看起來Python正在展望我將如何處理'if'語句中的'a',以便決定我在開始語句時所談論的是哪一個。 –

+0

@EliRose是的。在第一個例子中,'a'不是一個局部變量。 –

+0

Python在執行它之前已經解析了創建函數對象的函數,因此它並不是「正在尋找頭部」。通過分配給本地var創建*。如果你仔細查看函數對象的實現細節,你可以看到它。查看每個示例中的closure()。func_code.co_varnames','closure()。func_code.co_freevars'和'closure()。func_closure'。 –

相關問題