《36》リファクタリング:異なるエラー処理〈Python 3.0 版〉
実録:はじめてのプログラミング《記事一覧》
《36》リファクタリング:異なるエラー処理
《著》小粒ちゃん+α《監修》小泉ひよ子とタマゴ倶楽部
第3版♪2009/02/28 ● 2009年3月4日(水)
■ 概要
(エラー処理だけを対象に)異なるコードの断片から、新たなメソッドを抽出します。
リファクタリングが困難なときには「組み込み関数 eval を利用できないか」を検討します。 すると、新たなメソッドを抽出して、より洗練されたコードを記述できるようになります。
■ 関連記事
何が問題か:異なるエラー処理
《前述》した2つのメソッド __delitem__/remove では、
def __delitem__(self, key): ... while node: ... else: s = self.__class__.__name__ raise IndexError,"%s assignment index out of range"%s def remove(self, value): ... while node: ... else: s = self.__class__.__name__ raise ValueError,"%s.remove(x): x not in %s"%(s,s)
raise に続く例外が異なります。そこで、リファクタリングを実施して、これらの異なるコードの断片から新たなメソッドを抽出します。
リファクタリング:異なるエラー処理
メソッドを抽出するときには、もとの局所変数を新たな引数として再定義します。ここでは、1つの局所変数 s が対象になります。すると、
def _removeNode_delitem_error(self, s): raise IndexError,"%s assignment index out of range"%s def _removeNode_remove_error(self, s): raise ValueError,"%s.remove(x): x not in %s"%(s,s)
各メソッドに固有の例外とメッセージの内容だけを記述すればいいのが分かります。そこで、
class myList(object): def removeNode(self, value, tag): ... while node: ... else: s = self.__class__.__name__ eval("self._removeNode_%s_error(s)"%tag)
新たな引数 tag を導入して(その状況に合わせて)メソッドの名前を変化させます。つまり、呼び出すメソッド _removeNode_delitem_error/_removeNode_remove_error は、実行時に確定します。