2013-06-19 72 views
3

我想在我的類中有一個函數,我將僅使用此類的內部方法。我不會在這些方法的實現之外調用它。在C++中,我將使用在類的專用部分中聲明的方法。在python中實現這樣一個函數的最好方法是什麼?我正在考慮在這種情況下使用靜態裝飾器。我可以在沒有任何裝飾器的情況下使用函數嗎?self單詞Python中的私有方法

+4

Python中沒有真正的「私有」方法。看到[這個問題](http://stackoverflow.com/questions/70528/why-are-pythons-private-methods-not-actually-private) - 更具體地說,[這個答案](http://stackoverflow.com /一個/264775分之70555)。 – thegrinner

+0

我在問關於這個方法的好方法 – freude

+1

staticmethods和「private」方法是兩個不同的東西......你能解釋一下你真正想要的嗎?你想要一個既是靜態又是私人的方法嗎? – mgilson

回答

13

Python沒有的私人方法或屬性的概念,這全是關於你如何實現你的課程。但是,您可以使用僞私有變量(名稱修改),任何以__(兩個下劃線)開頭的變量都將變成僞私有變量。

docs

由於存在一個有效的用例爲類私有成員(即人名的具有名稱 避免名稱衝突由子類所定義的),有 對於這種有限的支持一種叫做名稱修改的機制。任何 表格__spam的標識符(至少兩個前導下劃線,在 最後一個尾部下劃線)被文本替換爲 _classname__spam,其中classname是帶有前導下劃線的當前類名稱。只要在類的定義內發生 ,就不考慮 到標識符的語法位置。

class A: 
    def __private(self): 
     pass 

所以__private現在居然變成靜態方法_A__private

例如:

>>> class A: 
...  @staticmethod   #not required in py3.x 
...  def __private(): 
...   print 'hello' 
...   
>>> A._A__private() 
hello 
+0

我可以只做def __private():沒有自我傳遞?然後在我的類中調用__private()。我可以在課堂外使用這個功能嗎? – freude

+0

@freude你已經將它定義爲靜態方法,然後將其稱爲:'A._A__private()' –

+0

在這種情況下,它是什麼意思靜態? – freude

1

你只是沒有做到這一點:

  • 的Python的方式是使用文檔字符串不記錄這些方法/成員,只能用「真正的」代碼註釋。公約是向他們追加一個或一個雙下劃線;

  • 然後你就可以在你的會員的前面使用雙下劃線,所以你它們是由本地的類(這主要是名稱重整,即外部類的成員的真實姓名變爲:instance.__classname_membername)。在使用繼承時避免衝突或在類的子項之間創建「私有空間」是有用的。

  • AFAICT,可以使用元類「隱藏」的變量,但違反蟒蛇的整個哲學,所以我不會詳談有關

+3

雙下劃線激活名稱修改。這絕對不是私人 –

+0

,這正是我所說的:你不這樣做,但你使用約定! – zmo

+0

您可以通過元類對屬性訪問進行模糊處理,您可以使用只讀屬性並使用裝飾器或元類實現私有/ setter/getter模式,但是隻能將某些事情混淆到某個人真正無法從內部獲取的唯一方法Python代碼是將其隱藏在C擴展中。 –

1

的Python只是沒有做私人。如果你喜歡,你可以按照約定,並用單下劃線前面的名字,但它是由其他編碼器,以尊重的紳士†時尚

†或gentlewomanly

1

很多偉大的東西在這裏與困惑使用領先的下劃線。就我個人而言,我從語言設計決策中受益匪淺,將所有內容都公開化,因爲它減少了理解和使用新模塊所需的時間。

但是,如果你確定要實現私有屬性/方法,你是願意當unpythonic,你可以做線沿線的東西:

from pprint import pprint 


# CamelCase because it 'acts' like a class 
def SneakyCounter(): 

    class SneakyCounterInternal(object): 

     def __init__(self): 
      self.counter = 0 

     def add_two(self): 
      self.increment() 
      self.increment() 

     def increment(self): 
      self.counter += 1 

     def reset(self): 
      print 'count prior to reset: {}'.format(self.counter) 
      self.counter = 0 

    sneaky_counter = SneakyCounterInternal() 

    class SneakyCounterExternal(object): 

     def add_two(self): 
      sneaky_counter.add_two() 

     def reset(self): 
      sneaky_counter.reset() 

    return SneakyCounterExternal() 


# counter attribute is not accessible from out here 
sneaky_counter = SneakyCounter() 

sneaky_counter.add_two() 
sneaky_counter.add_two() 
sneaky_counter.reset() 

# `increment` and `counter` not exposed (AFAIK) 
pprint(dir(sneaky_counter)) 

硬,你」想象的情況下,我想這樣做,但這是可能的。

+1

不錯的技巧)這是一個很好的例子,如何不使用python,但非常教育) – freude