《37》リファクタリング:第3のメソッド〈Python 3.0 版〉
実録:はじめてのプログラミング《記事一覧》
《37》リファクタリング:第3のメソッド
《著》小粒ちゃん+α《監修》小泉ひよ子とタマゴ倶楽部
第3版♪2009/02/28 ● 2009年3月5日(木)
■ 概要
(エラー処理だけを対象に)異なるコードの断片から、新たなメソッドを抽出します。
リファクタリングが困難なときには「組み込み関数 eval を利用できないか」を検討します。 すると、新たなメソッドを抽出して、より洗練されたコードを記述できるようになります。
■ 関連記事
何が問題か:第3のメソッド
メソッド pop も《前述》した2つのメソッド __delitem__/remove とよく似ています。
def pop(self): prev,node = self.head,self.head.next while node: if node==self.tail: value = node.item self.tail = prev prev.next = node.next del node return value prev,node = node,node.next else: s = self.__class__.__name__ raise IndexError,"pop from empty %s"%s
(強調した部分を除いて)その大半は同じです。どのメソッドも要素を削除するので、コードが重複するのは当然です。そこで、リファクタリングを実施して、これらの異なるコードの断片から新たなメソッドを抽出します。
リファクタリング:第3のメソッド
メソッドを抽出するときには、もとの局所変数を新たな引数として再定義します。
def _removeNode_pop_cond(self, node, value, n): return node==self.tail def _removeNode_pop(self, prev, node): # ----- before value = node.item self.tail = prev prev.next = node.next del node return value def _removeNode_pop_error(self, s): raise IndexError,"pop from empty %s"%s
しかし、まだ問題が残ります。それは、メソッド _removeNode_pop
def _removeNode_body(self, prev, node):
prev.next = node.next
del node
return ...
の本体が、メソッド _removeNode_body の本体とは似て非なることです。そこで、pop にも対処できるような工夫をします。
class myList(object): def _removeNode_body(self, prev, node, value=None): prev.next = node.next del node return value def _removeNode_pop(self, prev, node): # ----- after self.tail = prev return self._removeNode_body(prev, node, node.item)
メソッド _removeNode_body には、新たな引数 value を導入します。また、メソッド _removeNode_pop の本体では、このメソッドを再利用して、その結果をリターン値にすると、局所変数 value が不要になります。すると、メソッド _removeNode_pop は、__delitem__/remove/pop のすべてに対処できるようになります。
Tips
Last updated♪09/04/24