2016-09-08 185 views
1

我有一個(簡單)模塊,像這樣:參考外部範圍從Python類

import tkinter as tk 

__outerVar = {<dict stuff>} 

class Editor(tk.Frame): 
... 
    def _insideFunction(self): 
     for p in __outerVar.keys(): 
      <do stuff> 

我就用__outerVar得到一個NameError: name '_Editor__outerVar' is not defined當我嘗試實例化編輯器。儘管我沒有寫信給__outerVar,但我仍然試着在insideFunction的頂部放置「global __outerVar」,同樣的錯誤。

我敢肯定我只是誤解了一些Python範圍規則。幫幫我?

py 3.5

+0

蟒蛇的名字在工作中搗毀。爲什麼不只是'outerVar'並將它作爲'outerVar'在你的類中訪問? –

+0

我以爲_和__是唯一的約定,實際上表明瞭受保護的私有變量。我沒有意識到這個名字會變形。 – Marc

回答

3

Python替換任何以雙下劃線__開頭的名字,以模擬'私有屬性'。本質上__name變成_classname__name。這被稱爲名字改編,僅發生中的類如記錄in the docs

這種混淆不考慮標識符的語法位置完成的,只要它一類的定義內發生。

解決的辦法是不使用__name名稱,使用類似_name或只是name就足夠了。

作爲附錄,在PEP 8 -- Method Names and Instance Variables它指出:

Python的軋液這些名稱與類名:如果類Foo有一個名爲__a一個屬性,它不能被Foo.__a訪問。 (通過調用Foo._Foo__a仍然可以獲得訪問權。)通常,雙引號下劃線應該僅用於避免名稱與設計爲子類的類中的屬性衝突。

所以,除非你正在設計的案例子類名稱衝突可能是問題,不要使用雙引號下劃線。

3

您正在看到名稱有效。從documentation

任何標識符的形式__spam的(至少兩個前導下劃線,至多一個結尾下劃線)的文本上與_classname__spam,classname即當前的類名剝離前導下劃線(一個或多個)所取代。 只要它出現在類的定義內,就不會考慮標識符的語法位置。

至於我能想到的,解決這個問題的唯一辦法是在全球範圍內的東西,不以雙下劃線開始的__outerVar重命名。