1

次のようなプロパティを持つクラスがあります。

class Foo(object):
    def __init__(self):
        self._bar = 'bar'

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

    @bar.setter
    def bar(self, value):
        self._bar = value

そのクラスをインスタンス化し、それを辞書で使用して、次のようにプロパティに新しい値を割り当てました。

f = Foo()
d = {'x': f.bar}
d['x'] = 'baz'
print d['x'] # prints baz, as expected
print f.bar  # prints bar, not as expected

このように使用すると、プロパティのセッターが呼び出されないのはなぜですか?

編集:この視覚化により、物事はすでにかなり明確になりました。正しく理解すれば、辞書に格納されているのはFooプロパティを持つオブジェクトではなくbar、ゲッターの戻り値です。右?

4

2 に答える 2

1

同じキーが 2 回使用されると、辞書はその値を上書きします。

>>> test_dict = {'a': 1, 'b': 2, 'c': 3}
>>> test_dict['a'] 
1
>>> test_dict['a'] = 5
>>> test_dict
{'a': 5, 'c': 3, 'b': 2}

あなたのコードで

f = Foo()
d = {'x': f.bar} # map 'x' to f.bar - and your getter property is invoked
d['x'] = 'baz'  # remap 'x' to baz
print d['x'] # prints baz, as expected
print f.bar  # prints bar, again getter is invoked here

編集:

正しく理解すれば、辞書に格納されているのは、プロパティ バーを持つオブジェクト Foo ではなく、getter の戻り値です。右?

はい、ゲッターはいくつかのアクションを実行するために使用できます。たとえば、最初の文字が大文字のバーが必要だとすると、データを変更してゲッターで返すことができます。

@property
def bar(self):
    return self._bar.capitalize() 

同様に、setter は健全性テストにも使用できます。「stupid」という文字列をデータに保存する必要がないとします-次のようなことができます

@bar.setter
def bar(self, value):
    if value == 'stupid':
        raise ValueError("Stupid not allowed!")
    self._bar = value

基本的に、覚えておく必要があるのは、値が設定さsetterれると が呼び出され、値が取得されるとgetterが呼び出されるということです。ただし、コードでは、setterが呼び出されることはありません。

于 2013-07-04T17:54:32.673 に答える