2012-05-29 37 views
4

下面的代碼生成錯誤:Python的父類兒童私有變量的訪問

class A(object): 
    def say_something(self): 
     print (self.foo) 
     print(self.__bar) 

class B(A): 

    def __init__(self): 
     self.foo='hello' 
     self.__something='world' 


test=B() 
test.say_something() 

印刷的「你好」是成功的,但「世界」生成以下錯誤:

print(self.__bar) 
AttributeError: 'B' object has no attribute '_A__bar' 

我對此我感到驚訝,我希望我的父類有一個方法,可以訪問其子級保證的私有屬性。有沒有解決這個問題的標準方法?

附加問題:所以,如果我爲一個屬性使用單個下劃線,從不同的對象中使用它會不會是錯誤的?是一個單獨的下劃線說「我會使用這個,但你的用戶不應該」,或者甚至應該讓開發者把它看作是私有的。請問這段代碼是不好的風格:

class A(object): 
    def __init__(self): 
     self._foo='bar' 

Class B(object): 
    def __init__(self): 
     a=A() 
     b=A._foo 
+0

您可能會發現以下問題很有用:[Python中對象名稱之前的單下劃線和雙下劃線的含義](http://stackoverflow.com/questions/1301346/the-meaning-of-a -single-and-a-double-underscore-before-an-object-name-in-python) –

回答

9

您可以使用self._B__something來訪問它。但是,這不是你應該做的。正確的解決方案是將__bar重命名爲_bar

double-underscore name mangling背後的想法是爲了避免與子類/超類發生衝突 - 它並不意味着用於私有變量。如果一個變量應該被認爲是私人的/內部的,用一個下劃線作爲前綴。這不會導致任何特殊處理,但是每個python開發人員都會知道它不是包含該變量的類/模塊的公共API的一部分。

+0

沒錯。名稱修改機制的意圖是準確地獲得OP在這裏看到的行爲。它的意思是讓一個成員元素鏈接到1並且只有1個作用域。 –

+0

明白了。我在這裏找到了和你說的一樣的東西http://docs.python.org/tutorial/classes.html我想對於沒有什麼是真正私人的想法我還是有點不舒服。 –

+0

那麼,即使是在具有「真實」私有變量的語言中,總是有方法(反射或混淆內存)來訪問它們。 Python簡單地假定程序員很聰明,所以它不會真正實施私有變量。 – ThiefMaster

-1

我懷疑你缺少代碼中的東西..我沒有看到__bar在任何A類或B類..

+6

在StackOverflow上,我們使用適當的英文,即「你」和「是」而不是「u」和「r」。 – ThiefMaster

1

它的名字改編。任何以雙下劃線開頭的成員都會在Python中獲取名稱。您的代碼可以與任何其他成員一起使用,只要它們沒有以雙下劃線開頭。