2008-10-02 49 views
1

一個關於Python的非常好的東西一類是與你能說出具有相同的名稱作爲訪問變量簡單:子類化與私有成員

self.__value = 1 

def value(): 
    return self.__value 

是否有提供接入的簡單方法給我想要繼承的類的私人成員?通常我只想簡單地使用類中的原始數據對象,而不必一直使用訪問器和增變器。

我知道這似乎違背了私人和公共的一般想法,但通常我想要繼承的類是我自己的類之一,我很高興將成員公開給子類,但不是該類的實例。提供這種區分有沒有一種乾淨的方式?

回答

5

不方便,沒有進一步破解封裝。雙下劃線屬性通過爲其被訪問的類預先添加'_ClassName'來改變名稱 - 因此,如果您有'__value'屬性的'ContainerThing'類,該屬性實際上被存儲爲'_ContainerThing__value 」。更改類名稱(或重構指定屬性的位置)意味着打破嘗試訪問該屬性的所有子類。

這正是爲什麼雙下劃線名稱mangling(這不是真正的「私有」,只是「不方便」)是一個壞主意使用。只需使用單個前導下劃線。每個人都會知道不要觸摸你的'私人'屬性,你仍然可以在子類和其他方便使用的情況下訪問它。名稱 - 雙下劃線屬性的修改僅用於避免名稱衝突,這些名稱衝突對於特定於特定類的特定屬性非常罕見。它沒有提供額外的「安全性」,因爲即使名稱損壞的屬性也很容易訪問。

爲了記錄在案, '__value' 和 'value'(和 '_value')是不一樣的名字。下劃線是名字的一部分。

2

不知道該從哪裏引用,但關於訪問保護的以下聲明是Pythonic canon:「我們都同意這裏的成年人。

就像Thomas Wouters所說的那樣,一個單獨的前導下劃線是將屬性標記爲對象內部狀態的一部分的慣用方式。兩個下劃線僅提供名稱修改以防止輕鬆訪問該屬性。

之後,你應該想到的是磁帶庫的客戶不會去,並通過與「私有」屬性插手搬起石頭砸自己的腳。