2012-05-08 30 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