Python.use(better)《余録》インターフェース -- NotImplementedError

記事一覧 Python.use(better)《Python3.1》

《余録》インターフェース -- NotImplementedError

《著》小粒ちゃん+∞《監修》小泉ひよ子とタマゴ倶楽部
第0版♪2001/03/02 ● 第1版♪2003/05/25 ● 第2版♪2004/06/01 ● 第3版♪2009/02/28

事例:インターフェース

Java のインターフェースに相当する、いくつかの代替案があります。

■ 例外 NotImplementedError

例外 NotImplementedError を利用すると、プログラマーへの喚起を促せます。

class ListDemo(JPanel, ListSelectionListener):

        class TIPS(object):
            def _shouldNotImplemented(self, message):
                return NotImplementedError(
                    "def %s -- %s"%(message, self.__class__.__name__))
            
        class ActionListener(TIPS):
            def actionPerformed(self, *args):     #1:
                raise self._shouldNotImplemented("actionPerformed")
            __call__ = actionPerformed

        class HireListener(ActionListener, DocumentListener):
            def __call__(self, e):                #2:
                ...

        hireListener = HireListener(locals(), hireButton)

        self.employeeName = JTextField(
            10,
            actionPerformed = hireListener,       #3
            )

《Tips》Java では、インターフェースの検証を「コンパイラー」に委ねるしか術がありません。Python では、プロトコルの意義を「プログラマー」が自由に規定できます。

《Tips》これは、Smalltalk/shouldNotImplemented: に準拠したものです。

事例:コードの解説

■ #1: 例外を生成する
        class TIPS(object):
            def _shouldNotImplemented(self, message):
                return NotImplementedError(
                    "def %s -- %s"%(message, self.__class__.__name__))
            
        class ActionListener(TIPS):
            def actionPerformed(self, *args):     #1:
                raise self._shouldNotImplemented("actionPerformed")
            __call__ = actionPerformed

ここで規定したメソッド actionPerformed を、子孫クラスで再定義しないと、実行時に例外 NotImplementedError を生成します。

  • メッセージには、インスタンス self が属するクラスの名前 __class__.__name__ が含まれます。
  • 実際には、actionPerformed の代わりに、__call__ を再定義します。つまり、__call__ を再定義しないと、例外 NotImplementedError を生成します。

すると、実行時に次のようなメッセージ

Exception in thread "AWT-EventQueue-0" Traceback (most recent call last):
  ...
NotImplementedError: def actionPerformed -- HireListener

を出力したときには、子孫クラス HireListener でメソッド actionPerformed(実際には __call__)を再定義していないのが分かります。

■ #2: 特殊メソッド __call__
            def __call__(self, e):                #2:
                ...
  • メソッド呼び出し () に呼応して、その動作を規定するのが、特殊メソッド __call__ です。
■ #3: リスナーインタフェース actionPerformed
        self.employeeName = JTextField(
            10,
            actionPerformed = hireListener,       #3
            )
  • テキストフィールドに入力 actionPerformed すると、発生したイベントに呼応して、リスナー hireListener の特殊メソッド __call__ を起動します。

》こちらに移動中です《
TOP


関連記事

Last updated♪2009/10/14