作者: 機械伯爵
日時: 2005/1/28(11:52)
 機械です。

 Python はオブジェクト指向言語ですが、Smalltalk で
言う「メッセージ指向」かと言われると、やや問題があ
ります。

 というのも Python オブジェクトでは、関数もメソッ
ドもそれ自身が「オブジェクト」であり、メッセージに
相当するものではありません。

 メッセージはいわば演算子ですから、Smalltalk で、

	object message.

と書けば、message の部分が当然メッセージですが、
Python では・・・

	object method()

と書くと、メッセージに相当するのは「method()」では
なく「()」になります。

 つまり、object.method というオブジェクトに「()」
を送っている、ということになります。

 ここで、一つのオブジェクトに複数のメッセージを順々
に送る場合を考えてみましょう。

 もし、メソッドがオブジェクト自身を返す場合は、
Smalltalk でも Python でも似たような書き方ができま
す。

Smalltalk
	object mes1 mes2 mes3.

Python
	object.mes1().mes2().mes3()

 では、Smalltalk のカスケードのように、オブジェク
トに順々にメッセージを送る方法はあるのでしょうか?

Smalltalkのカスケード

	object	mes1;
		mes2;
		mes3.

 たとえば、このようなコードを書いたとしましょう。

for x in (mes1,mes2,mes3):
	object.x()

 このコードは「mes1 とか mes2 とか mes3 ってナニ?」
というエラーメッセージが帰ってきます。

 これは、Python が object.mes1 という名前は認識し
ても、mes1 という名前は認識しないためです。

 だからといって・・・

for x in (object.mes1,object.mes2,object.mes3):
	x()

 は、コード整理のうまみがありません。

 現在、with というキーワードの導入が検討されている
ようで、将来的には

with object
	mes1()
	mes2()
	mes3()

 といった書き方が出来るようですが、現在の方法でも
なんとか出来ないでしょうか?

 かなりトリッキーですが、こんな書き方は可能です。

for x in ('mes1','mes2','mes3'):
	object.__dict__[x]()

 __dict__ 属性は、辞書形式で内部のフィールドやメソ
ッドにアクセスするプロトコル(と、新しいクラスには
書いてある)なので、文字列を使って、カスケードと同
じように使うことが可能です。

 なお、数が多くなると、いちいちクォートで囲むのが
面倒になりますので、

m = 'mes1 mes2 mes3 mes4 mes5 mes6 mes7 mes8 mes9'.split()
for x in s:
	object.__dict__[x]()

 では、引数を含めた書き方はどうでしょうか?

m = 'mes1(1) mes2(2) mes3(3) mes4(4) mes5(5)'.split()
for x in s:
	exec 'object' + x

 ・・・これはさすがにやりすぎ、ですね・・・

※限りなくパフォーマンス悪そう・・・

   /機械伯爵/