2012-08-24 88 views
3

今天我看到 - python將_$CLASSNAME$添加到名稱爲__的方法中。Python'隱藏'方法__

簡單的例子:

>>> class A: 
...  def a(self): 
...   self.b() 
...  def b(self): 
...   print('A.b') 
...   
>>> class B(A): 
...  def b(self): 
...   print('B.b') 
...   
>>> B().a() 
B.b 

這項工作,但是:

>>> class A: 
...  def a(self): 
...   self.__b() 
...  def __b(self): 
...   print('A.b') 
...   
>>> class B(A): 
...  def __b(self): 
...   print('B.b') 
...   
>>> B().a() 
A.b 

爲什麼?我不知道,所以我推薦它。這裏是:

>>> print([fn for fn in dir(B) if fn[-2:] != '__']) 
['_A__b', '_B__b', 'a'] 

爲什麼python做到這一點?有沒有辦法繞過呢?

回答

7

這就是所謂的名稱修改,並防止與父類和子類發生意外名稱衝突。你不能(也不應該,很多完美的代碼使用它)禁用它。你可以規避它,但是你也不應該這樣做(它非常醜陋,你可以避免它,當你需要訪問它時,你不應該允許名字混亂)。只需使用一個下劃線作爲私人功能,您可以隨時隨地使用這些私人功能。

請參閱tutorial,但忽略對此表示「私有」變量的任何引用。除非您在C++/Java/C#/ ... private變量中使用private變量(與子類中可見的protected相反),否則它不會用於子類。即使這樣,這也是一個有缺陷的類比。

+0

所以它更像保護 - 子類不能使用它。 –

+0

@xiado在所有語言中,我都知道該功能區分'private'和'protected','privateted'是子類不可訪問的,因此更接近於此。你說的是哪種語言的「保護」? – delnan

+0

不好意思 - 我在想另外一件事 - 你得到了很多。 –

10

雖然這些都不是python嚴格執行的,但雙下劃線的命名約定意味着「私人」,而單個下劃線意味着「受保護」。

雙下劃線旨在通過使用相同的名稱來防止子類導致錯誤。通過用類名命名它們,定義類可以確定它的變量將保持有效。

單個下劃線表示子類可以自由訪問和修改與超類共享的相同屬性。

兩種形式建議任何外部類不應該訪問這些。

class A(object): 

    __private = 'private' 
    _protected = 'protected' 

    def show(self): 
     print self.__private 
     print self._protected 

class B(A): 
    __private = 'private 2' 
    _protected = 'protected 2' 

a = A() 
a.show() 
#private 
#protected 

b = B() 
b.show() 
#private 
#protected 2 

本實施例表明即使類B定義的新__private,它不影響繼承show方法,該方法仍然訪問原始超類的屬性。然而,_protected被修改,並且超類show方法反映了這一點,因爲它們是相同的屬性。

+4

+1爲「建議」。 –

+0

只是要注意,'__private'不是真正的私有的,你仍然可以通過'i = B()訪問和操作它。 i._B__private'。我有一種方法使事情幾乎真正的私人化(仍有'__closure__'訪問):https://www.daniweb.com/programming/threads/510759/snippet-how-to-privatize-attributes-of-a-時隙級#post2229436 – Tcll