9

@propertyオブジェクトのインスタンス変数への変更が、必要なメソッドによって確実にラップされるようにするために使用します。

論理的に変更してはならない変数がインスタンスにある場合はどうでしょうか? たとえば、Process のクラスを作成している場合、各 Process インスタンスには、頻繁にアクセスされるが変更されるべきではない PID 属性が必要です。

そのインスタンス変数を変更しようとしている人を処理する最も Pythonic な方法は何ですか?

  • ユーザーがすべきではないことを変更しようとしないことを単に信頼しますか?

  • プロパティを使用しますが、インスタンス変数が変更された場合に例外を発生させますか?

  • 他の何か?

4

4 に答える 4

9

変数の名前の前に。を付け__、読み取り専用プロパティを作成すると、Pythonが例外を処理し、変数自体が誤って上書きされないように保護されます。

class foo(object):
    def __init__(self, bar):
        self.__bar = bar

    @property
    def bar(self):
        return self.__bar

f = foo('bar')
f.bar         # => bar
f.bar = 'baz' # AttributeError; would have to use f._foo__bar
于 2009-10-06T19:08:31.760 に答える
3

ユーザーを単純に信頼することは、必ずしも悪いことではありません。一度使用して破棄する簡単な Python プログラムを書いているだけの場合は、ユーザーが pid フィールドを変更しないことを信頼するだけで十分です。

私見では、読み取り専用フィールドを強制する最も Pythonic な方法は、フィールドを設定しようとしたときに例外を発生させるプロパティを使用することです。

だから、私見、あなたはこのことについて良い本能を持っています。

于 2009-10-06T19:11:39.213 に答える
1

プロパティと非表示の属性( 1つのアンダースコアが前に付いている)を使用するだけです。

単純なプロパティは読み取り専用です!

>>> class Test (object):
...  @property
...  def bar(self):
...   return self._bar
... 
>>> t = Test()
>>> t._bar = 2
>>> t.bar
2
>>> t.bar = 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

二重アンダースコアで非表示にすることは、実装を非表示にするためではなく、サブクラスの属性と衝突しないようにするために使用されます。たとえば、ミックスインを考えてみましょう。非常に注意する必要があります。

属性を非表示にするだけの場合は、単一の下線を使用します。ご覧のとおり、追加する魔法はありません。集合関数を定義しない場合、プロパティはメソッドの戻り値と同じように読み取り専用になります。

于 2009-10-06T22:24:49.260 に答える
1

多分あなたはオーバーライドできます__setattr__か?の行で、

def __setattr__(self, name, value):
    if self.__dict__.has_key(name):
        raise TypeError, 'value is read only'
    self.__dict__[name] = value
于 2009-10-06T19:02:58.803 に答える