2013-11-22 15 views
7

在Python(2.7.6測試)中,所有變量都是在編譯時靜態綁定到範圍的 。這個過程是非常 在http://www.python.org/dev/peps/pep-0227/描述和 http://docs.python.org/2.7/reference/executionmodel.html爲什麼靜態綁定對類和函數的工作方式不同?

它明確地指出:「如果一個名字綁定操作時 一個代碼塊內的任何地方,塊 內名稱的所有用途都被視爲對當前引用塊。」

函數是一個代碼塊,以便與失敗,因爲x 其使用之後被分配以下代碼(所以在編譯時將其定義本地 ,因爲它是在函數某處分配,但在執行 時間,它在綁定之前使用)。

x = 1 
def f(): 
    print x 
    x = 2 
    print x 

>>> f() 

Traceback (most recent call last): 
    File "<pyshell#46>", line 1, in <module> 
    f() 
    File "<pyshell#45>", line 2, in f 
    print x 
UnboundLocalError: local variable 'x' referenced before assignment 

類也是一個代碼塊,所以我們應該觀察完全 相同的行爲。但這不是我觀察到的。 請看下面的例子:

x = 1 
class C(): 
    y = x + 10 
    x = 2 
    def __init__(self): 
     print C.y 

>>> C.x 
2 
>>> C.y 
11  
>>> C() 
11 
<__main__.C instance at 0x00000000027CC9C8> 

作爲類定義是代碼塊,這 塊內的任何分配應該使局部變量。所以x應該是本地的C的 類,所以y = x + 10應導致UnboundLocalError。 爲什麼沒有這樣的錯誤?

+0

這個線程http://stackoverflow.com/questions/12810426/differences-between-class-block-and-function-block-in-python指的是同樣的問題,但沒有強給出解釋。 PEP-0227和python 2.7執行模型在功能塊或類塊之間沒有任何區別 – user3022222

+0

這是一個常見的範圍界定問題。請注意以下內容之間的命名空間的區別:''和''。區別在於'__main__'命名空間。 – VooDooNOFX

+0

此外,這是很密切的關係http://stackoverflow.com/questions/12810426/differences-between-class-block-and-function-block-in-python – VooDooNOFX

回答

3

是的 - 它似乎是相當具有誤導性的文件。一個類定義不實際工作相當的其他正常塊相同:

global_one = 0 

class A(object): 
    x = global_one + 10 
    global_one = 100 
    y = global_one + 20 
    del global_one 
    z = global_one + 30 

a = A() 
print a.x, a.y, a.z, global_one 

結果:10, 120, 30, 0

,如果你試圖用一個函數同樣的事情,你對你的第一次訪問得到UnboundLocalErrorglobal_one

這樣做的原因是,類定義爲正常訪問父範圍,但是,所有名稱分配不修改局部範圍,但實際上被捕獲到類的數據屬性字典。文檔中有關於此的提示,但它肯定不是很明顯。

相關問題