2017-07-19 60 views
1

您好我對python中的變量範圍有點困惑。請好好解釋下面的片段之間的區別。UnboundLocalError:在賦值之前引用的局部變量爲什麼在這種情況下不應用LEGB規則

ⅰ)

class Test(object): 
    a_var = 1 

    def a_func(self): 
     self.a_var = self.a_var + 1 
     print(self.a_var, '[ a_var inside a_func() ]') 


    if __name__=='__main__': 
    t=Test() 
    t.a_func() 

O/P:2內a_func a_var()]

class Test(object): 
    a_var = 1 

    def a_func(self): 
     a_var = a_var + 1 
     print(a_var, '[ a_var inside a_func() ]') 


if __name__=='__main__': 
    t=Test() 
    t.a_func() 

O/P:UnboundLocalError:局部變量 'a_var' 分配之前引用

爲什麼LEGB規則不適用於第二種情況,如果它不能從類別爲enclosedesope中獲得價值。好心解釋。提前致謝。

回答

1

這可能看起來很奇怪(而且是),但是你不會在class之上關閉,它只會超過def。 「e關閉」範圍L E GB中提到的範圍只是談論功能定義;在這裏沒有一個階級街區。

這種奇怪的行爲是歷史上將類添加到Python中的一種人爲因素。類範圍不是真正的範圍。 Python並不總是有類,而且在類定義期間只存在一些令人毛骨悚然的「中間範圍」:在內部,類體下的代碼或多或少只是在臨時範圍內運行exec,結果被分配給類名稱。這是一種非常簡單的「插入式」方法,可以讓OOP進入語言當中,這也是Python將外顯的self作爲有意識的語言設計選擇的原因。

要從方法內的「類範圍」中訪問a_var,必須通過self.a_varTest.a_var使用屬性訪問。兩者都應該工作。您也可以在班級定義期間直接在班級進行訪問,但由於您仍在臨時範圍內,這只是本地訪問的另一個示例(EGB)。

這在execution model部分下有記錄(儘管不是特別清楚)。

Class definition blocks and arguments to exec() and eval() are special in the context of name resolution. A class definition is an executable statement that may use and define names. These references follow the normal rules for name resolution with an exception that unbound local variables are looked up in the global namespace. The namespace of the class definition becomes the attribute dictionary of the class. The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods – this includes comprehensions and generator expressions since they are implemented using a function scope.

+0

謝謝我現在很清楚,從哪裏得到這種類型的信息我在某些書中沒有找到它「這看起來很奇怪(而且是),但是你沒有在課堂上關閉,它只是在def上,LEGB中提到的「封閉」範圍只是在討論函數定義;類塊不在這裏計數。「你能否給我提供一些好文章的鏈接,我可以在類中獲得與類,變量和訪問方法以及棘手的變量初始化相關的清晰概念。謝謝 – user3256451

+0

我添加了一個文檔參考。 – wim

相關問題