《03》依存性:change&update(3)〈Python 3.0 版〉
《Previous| |Next》
Python à la carte《記事一覧》
《03》依存性:change&update(3)
関連記事
モデルの変化に呼応する複数のオブジェクト
モデルの変化に呼応する複数のオブジェクトを設定できると便利です。
>>> m1 = ValueHolder(); m1.name = "red" >>> m1.compute(lambda e: print("{0}: {1!r}".format(m1.name,e))) <__main__.BlockValue object at 0x106270>
モデル(として、ValueHolder のインスタンス)m1 を生成します。メソッド compute を使って、モデルの動作を規定(すると同時に、BlockValue のインスタンス 0x106270 を生成)します。ここでは、モデル m1 の値 e を出力するとともに、そのインスタンス属性 .name の値を出力します。これは、モデルを識別するための便宜的なものです。そこで、
>>> m1.value("A") red: 'A'
メソッド value を呼び出すと、モデル m1 の値が変化(changed)するとともに、更新(update)に必要な処理をします。すると、メソッド compute で指定した処理に伴って、モデル m1 を識別する red に続いて、その値 'A' を出力します。つまり、value の実引数 "A" が、compute で指定した lambda e: の仮引数に対応します。
>>> BlockValue(lambda e: print(repr(e),"->",ord(e)),[m1]) <__main__.BlockValue object at 0x106490>
(他のモデルの変化に呼応する)モデルとして「第2の」BlockValue のインスタンス 0x106490 を生成します。このとき、第1引数には、他のモデルの変化に呼応する処理を指定します。また、第2引数には、その状態が変化したときに通知をして欲しいモデルを指定します。これは、モデル m1 の変化に呼応して、その値(文字列)e と、対応する文字コード ord(e) を出力します。
>>> m1.changed() red: 'A' 'A' -> 65
メソッド changed を呼び出すと(モデル m1 の値は変化せずに)更新に必要な処理だけをして、最初の出力に続いて「第2の」BlockValue で処理した値を出力します。このように、更新に必要な処理は、いつでも追加できます。これは、モデルの動作を「実行時に」追加できることを意味します。そこで、
>>> BlockValue(lambda e: print(repr(e),"->",e.lower()),[m1]) <__main__.BlockValue object at 0x106550>
(他のモデルの変化に呼応する)モデルとして「第3の」BlockValue のインスタンス 0x106550 を生成します。これは、モデル m1 の変化に呼応して、その値(文字列)e と、対応する小文字 e.lower() を出力します。
>>> m1.changed() red: 'A' 'A' -> 65 'A' -> a
メソッド changed を呼び出すと(モデル m1 の値は変化せずに)更新に必要な処理だけをして、2つの出力に続いて「第3の」BlockValue で処理した値を出力します。
>>> m1.value("B") red: 'B' 'B' -> 66 'B' -> b
メソッド value を呼び出すと、モデル m1 の値が変化(changed)するとともに、更新(update)に必要な処理をします。すると、3つの BlockValue で指定した処理に伴って、変化したモデル m1 の値 'B' に依存するいくつかの情報を出力します。
モデルの変化に呼応する複数のオブジェクト
>>> m2 = ValueHolder(); m2.name = "blue"
>>> m2.compute(lambda e: print("{0}: {1!r}".format(m2.name,e)))
<__main__.BlockValue object at 0x106bb0>
以前と同様に、モデル(として、ValueHolder のインスタンス)m2 を生成します。メソッド compute を使って、モデルの動作を規定(すると同時に、BlockValue のインスタンス 0x106bb0 を生成)します。そこで、
>>> BlockValue(lambda e: print(repr(e),"->",hex(ord(e))),[m2])
<__main__.BlockValue object at 0x106bf0>
(他のモデルの変化に呼応する)モデルとして「第2の」BlockValue のインスタンス 0x106bf0 を生成します。これは、モデル m2 の変化に呼応して、その値(文字列)e と、対応する文字コードを16進数形式で出力します。
>>> m2.value("A") blue: 'A' 'A' -> 0x41
メソッド value を呼び出すと、モデル m2 の値が変化(changed)するとともに、更新(update)に必要な処理をします。すると、メソッド compute で指定した処理に伴って、モデル m2 を識別する blue に続いて、その値 'A' を出力した後で、BlockValue で指定した処理に伴って、対応する文字コード 0x41 を出力します。さらに、
>>> m2.compute(lambda e: print("{0}: {1}".format(m2.name,ord(e)))) <__main__.BlockValue object at 0x106e70>
メソッド compute を使って、新たなモデルの動作を規定(すると同時に、BlockValue のインスタンス 0x106e70 を生成)します。そこで、
>>> m2.changed() blue: 'A' 'A' -> 0x41 blue: 65
メソッド changed を呼び出すと(モデル m2 の値は変化せずに)まず、第1のメソッド compute で指定した形式で出力します。次に、BlockValue で指定した形式で出力します。最後に、第2のメソッド compute で指定した形式で出力します。
Tips
compute を使って「モデルが自分に依存する処理」を規定する方法と、BlockValue を使って「他のモデルに依存する処理」を規定する方法とを、その用途に応じて使い分けます。