2013-04-13 103 views
1

我在http://pydanny.com/python-dictionary-as-a-class.html處發現了以下代碼。代碼工作正常,我有點理解爲什麼它只是一個類似的代碼,在它下面給出錯誤。在Python中實現類作爲字典

def newclass(**kwargs): 
""" Use kwargs.update() method to handle inheritance """ 

def set(key, value): 
    """ Sets key/value to the kwargs. 
     Replicates self/this clumsily 
    """ 
    kwargs[key] = value 
kwargs['set'] = set 
return kwargs 

我試代碼:

def closing(): 
    x=1 
    def closed(): 
     print(x) 
     x=x+1 
    return(closed) 

a=closing() 
a() 

錯誤消息:

Traceback (most recent call last): 
File "<pyshell#606>", line 1, in <module> 
a() 
File "<pyshell#604>", line 4, in closed 
print(x) 
UnboundLocalError: local variable 'x' referenced before assignment 

當我使用 '非本地X' 在它工作的封閉功能,但怎麼來的初始代碼作品,未經「外地」。 我的理解是,它是一個閉包,內部函數將保持外部(自由)變量的引用,並且無論何時調用內部函數,它都能夠對該閉合變量進行操作,但當然我還沒有理解它的某些部分正常。 請幫我清除我缺少的概念。 謝謝所有回答的人。 SO太有幫助了。

+0

它看起來好像你的第一個片段有空白錯誤 – hdgarrood

回答

2

當我在封閉函數中使用'nonlocal x'時,它的工作原理是什麼,但是初始代碼如何在沒有'nonlocal'的情況下工作。

在第一個片段中,您正在改變現有的kwargs值。您不會爲其分配新的值,也不會爲其他名稱分配新的值。

但在第二個片段中,您將爲x分配一個新值。這迫使x是本地的(除非你另有說明)。因此,您的x+1是對尚未分配的局部變量的引用。因此錯誤。

有關更加嚴格的解釋,請參閱文檔中的Naming and binding。相關位是:

在程序文本的名稱中的每一個發生是指建立在包含使用最裏面的功能塊的名稱的結合...

當一個名稱以代碼塊中使用,如果名稱是在塊束縛的情況下使用最近的封閉範圍內解決......

,它是塊的局部變量,除非聲明爲nonlocal ...

要了解如何這是在封面下工作的,您還需要閱讀The standard type hierarchy中的函數和代碼對象。您可能不需要知道該部分的理解,但對於調試,您可能需要檢查__closure__和其他屬性。

+0

你是對的。我在執行控制函數中檢查了變量的id,並且在函數死亡和內存地址保持不變之後,我(錯誤地)認爲進一步的分配也會使用相同的地址。我沒有意識到這個任務不同於突變。非常感謝您的時間和其他鏈接。 –