メソッドのself (4)
メソッドの第一引数にselfを指定する1つのメリットを見つけた。Guidoさんも言及していたかもしれないがメリットは、foo.meth(arg)を、Foo.meth(foo, arg)と書けることである。これは、高階関数として使う場合にメリットがある。
例えば、複数のsetのオブジェクト全てにintersectionをしたい場合、以下のようにできる。
>>> s1 = set([1,2,3]) >>> s2 = set([2,3,4]) >>> s3 = set([3,4,5]) >>> L = [s1, s2, s3] >>> >>> s1.intersection(s2) set([2, 3]) >>> set.intersection(s1, s2) set([2, 3]) >>> >>> reduce(set.intersection, L) set([3])
これとは違うが、3.0に面白いメソッドが追加されていて、以下のようなことができる。
>>> import operator >>> s1 = {1,2,3} >>> s2 = {2,3,4} >>> operator.methodcaller('intersection', s2) <operator.methodcaller object at 0x00CBF1E8> >>> _(s1) {2, 3}
結局、メソッドのレシーバや引数を自由に入れ替えできるような機能があれば、OKかもしれない。
追記(2008/12/10):
operator.methodcallerは残念ながら引数としてレシーバのみを取る関数しか戻してくれない。以下のようにできない。
>>> import operator >>> operator.methodcaller('intersection') <operator.methodcaller object at 0x00CBF1E8> >>> _(s1, s2) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: methodcaller expected 1 arguments, got 2
Haskellのように自動的にカリー化される機構があれば以下のようにできる。
>>> operator.methodcaller s2 s1 # この場合s1とs2は対称で交換可能なので methodcaller s1 s2でも良い
Haskellのような1引数しか取れないという仕組みはどうなのだろう?関数のカッコは面倒だが、カッコを省略できるということに関してあまり良いイメージがない。