2012-05-08 17 views
2

クラスは外部アクセスからその属性のどれをどれだけ保護できますか?例えば、従来の_secret属性を持つクラスは、元の値が簡単にPythonの "private"属性へのアクセスを防止する

をアクセスします。

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のコンテキスト内では、メモリを調べてください)

+0

私はこれが重複していると確信していますが、属性を保護する興味深い試みで答えがたくさんある質問が表示されていますが、私の検索では何も見つかりませんでした – dbr

+0

https://plus.google.com/114760865724135687241/投稿/ HAqFzi3fnux – bossylobster

+4

[我々はすべてここに大人に同意している](http://stackoverflow.com/questions/70528/why-are-pythons-private-methods-not-actually-private)。 –

答えて

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__'をオーバーロードして、スーパークラスへの呼び出しをpublic属性(privateの場合は拒否)にすることができますが、private属性でもこれを行うことができます。 – Shep

関連する問題