2012-05-08 67 views
2

類可以在多大程度上「保護」其外部訪問中的某個屬性?防止在Python中訪問「private」屬性

例如,與常規的_secret屬性的類,原始值被容易地訪問:

class Paranoid(object): 
    def __init__(self): 
     self._secret = 0 

    def set(self, val): 
     self._secret = val * 10 

    def get(self): 
     return self._secret/10 

p = Paranoid() 
p.set(123) 
print p.get() # 123 
print p._secret # 1230, should be inaccessible 

如何可以接入到_secret變得更加困難?

這裏沒有實際的應用,我只是好奇,是否有新穎的方式讓它更難訪問(在Python的上下文中 - 因此忽略了一個事實,例如,可以將調試器附加到Python進程並檢查內存)

+0

我敢肯定,這是重複的,我記得看到一個問題,有一串有趣的嘗試,在保護屬性的答案..但我的搜索沒有發現任何 – dbr

+0

https://plus.google.com/114760865724135687241/帖子/ HAqFzi3fnux – bossylobster

回答

4
>>> def Paranoid(): 
...  _secret_dict = {'_secret': 0} 
...  class ParanoidClass(object): 
...    def set(self, val): 
...      _secret_dict['_secret'] = val * 10 
...    def get(self): 
...      return _secret_dict['_secret']/10 
...  return ParanoidClass() 
... 
>>> p = Paranoid() 
>>> p.set(123) 
>>> p.get() 
123 

這讓我想起了Steve Yegge blog post

+0

不會輕易地爲任何公共界面編寫類成員,但很有效。 +1的博客文章。 :D – Darthfett

+1

不起作用:'>>> p.get.im_func.func_closure [0] .cell_contents {'_secret':1230}' – ch3ka

+0

哇,我沒有意識到閉包對於在定義的類中定義的方法在一個函數中!你可以使你的「祕密」變量爲'object()',這樣你就可以在其上存儲屬性;這可能更乾淨。儘管如此,這並不是真正的私有,只是有點隱藏:'print p.get.func_closure [0] .cell_contents' – kindall

6

您可能正在尋找getters and setters。稍微少一些的方法是使用__secret,它會調用名稱改變來將其轉化爲_Paranoid__secret

但是,我應該注意到python社區並沒有像一些語言那樣真正重視隱私。或者俗話說we're all consenting adults here

+1

這與OP示例相同,因爲您可以輕鬆修改'_Paranoid__secret'變量。他希望能夠複製其他語言提供的「私人」訪問限制,由編譯器或其他方式執行。 – vz0

+0

是的,這不是真正的正確答案。對象通過用戶所做的相同接口調用它們的屬性,據我所知,這使得真正的隱私無法實現。您可以重載'__setattr__'和'__getattribute__'來調用超類的公共屬性(並且拒絕私有),但用戶也可以使用私有屬性來實現。 – Shep