2009-03-22

_ ABCとインターフェース

先日Zope 2.12のalpha1がリリースされて、 いろいろ面白いことになっているので、 手元で遊んでみていました。 Zope 2.12自体でも、Zope 3のオブジェクトがそのまま使えるようになったりとか(aq_parentとかをハックしている)、いくつか楽しい変更があるんですが、Python 2.5/2.6をサポートしたのはかなり大きな進展です。

残念ながら手元の環境のRPMはPython 2.5.2なので、Zope 2.12が対応している2.5.4 or better、2.6.xという条件に当てはまりません。 面倒くさいので、手っ取り早く2.6.1をダウンロードしてきて、手元でビルドして使ったんですが、一応動いているように見えます。

Zope自体の話を書いてもいいんですが、ここではPython 2.6の話を書きます。 せっかく最近のPythonが使えるようになったんだから、この際Python界がどう発展しているのか調べてみようと思い立ちました。 詳細は、What’s New in Python 2.6を見てほしいのですが、その中でも PEP 3119 -- Introducing Abstract Base Classesへの対応が興味深いと感じました。

Abstract Base Classes(ABCs)というのは、手っ取り早くいうと、C++でいうところのvirtualが使われたクラスみたいなものです。 PEP 3119にたくさん書いてありますが、純粋なDuck typingだと、 あるオブジェクトが何をしてくれるのかがよくわかりません。

例のPEPでは、InvocationとInspectionという言葉を使っていますが、 Invocationというのはオブジェクトを実際に使ってみて、それで何かが起きるってことで、Inspectionというのはオブジェクトを動かさずに何ができるか調べるってことです。

InvocationはDuck typingで普通にやってるわけですが、 Inspectionは今のPythonの組込み機能だと型を調べるしかありません。 そうすると、Duck typingができなくなってしまいます。 現実にはもうちょっと「合わせ技」みたいなことがやりたくなることが多々あるわけです。 つまり、「このオブジェクトはこの型だからこれができる」みたいなのじゃなくて、「このオブジェクトはこれができると言っているからこれができる」みたいな。

それで、ABCっていうのは、一種のメタクラスを使って、そういう「これはこのことができるもの」みたいなことを意味するクラスを作って、それをクラスの継承関係に混ぜ合わせようってわけ。

Pythonをまともに知っている人なら誰でも知っているように、 「ABCsってzope.interfaceと被ってない?」と疑問に思うわけです。 zope.interfaceは、クラスの継承関係とは完全に分離してインターフェースを管理し、インターフェース・クラスには絶対にコードを書かないという方針です。 しかし最終的にできることはかなり似通っています。

実際、議論は白熱していて、 PEP 3119の最後の方にはInterface擁護者を煽っているとしか思えない記述があったり、 [Python-3000] ABC's, Roles, etcで始まるスレッドで全くかみ合ってなかったり、 PEP 3124(現在は保留状態)ではInterfaceなんか使わなくてもAdaptationはABCsで可能だと提案したり、 Explaining Why Interfaces Are GreatでTwistedの人が強力にzope.intefaceをサポートしたり。

みんなあちこちでいろんなことを言ってますが、 簡単にまとめると、ABC擁護者の言い分は

  • Adaptationなんて、Zopeぐらい(滅多にない巨大なプロジェクト)でしか役に立たない。
  • Interfaceは、問題そのものではなくて、解決方法に重点を置きすぎる。
  • AdaptationよりGeneric Functionの方がよい。(GFはどっちでもできるけれど、それならABCsの方が単純でよい。)
  • ABCsなら自分が必要な部分だけ実装すればいいが、Interfaceだと全部作らないといけない。

Interface擁護者の言い分は

  • ABCsだと、どれが実装でどれがインターフェースのことを意味しているのかがごた混ぜ。だから、Documentation(インターフェースの人間用の説明)にならないし、isinstanceとかissubclassがクラス関係のことを意味しているのか何なのかわからない。
  • ABCsだと、Verification(ある実装が本当にインターフェースを満たしているか確認すること)ができない。
  • ABCsは、クラスに頼りすぎ。そんなのOOPじゃない。zope.interfaceはどんなオブジェクトにも使える。
  • ABCsだって汎用的なメソッドを先に書くことになるじゃないか。overloadとか先に書くことになるじゃないか。云々。

言語屋さんの喧嘩を見ていると確かに楽しいんですけど、 実際的なプログラマである私の立場からすれば、 どっちにするにせよ、どっちかにならないと面倒くさいと感じます。 実際、他の人が作ったライブラリを使おうとして、それが自分の使っていない方法を使っていたりすると、外部からいちいち調整してあげないといけなくなってしまうからです。 これが私がときどき言っている「制限がある方が出来ることが増える」というパターンの一種で、みんながてんでばらばらなことをし始めると、 くっつけられなくなるので困るんですね。 「後付けの方が自由度が高いので出来ることが多い」なんて主張している人を見ると、どんだけナイーブなんだ、この人は、と感じてしまいます。

個人的には、分離するzope.interfaceの方が良い気がするんですけどね。 しかし、私はC++のクラス指向にうんざりしたり、zopeに洗脳されていたりするんで、バイアスのかかった意見なのかもしれません。

本日のツッコミ(全1件) [ツッコミを入れる]
_ yutakashino (2009-03-22 20:07)

僕もzope.interface派ですね。Abstract Base Classesでもinterfaceチックなことはできるでしょうけれど、個人的にはinterfaceとZCMLに慣れちゃったから、わざわざABCsを使う気はないですね。

本日のTrackBacks(全1件) []
_ カビ対策:カビ対策 (2009-08-25 00:58)

カビ対策をして家の中からカビを除去しましょう。


トップ «前の日記(2009-02-28) 最新 次の日記(2009-04-01)»