Python.use(better, follow=”K&R”) リファクタリング 7/10

Previous|7/10|Next
Python.use(better, follow=”K&R”) # for novice 記事一覧

改訂♪2008/10/04

リファクタリング:メソッド固有の処理

[Python]何が問題か?


# cz_08.py -------------------------------------------- before ---
class HashTable:
def __getitem__(self, key):
e = self._detect(key)
if e:
return e[key]
else:
raise KeyError, key # NOTICE !!

def get(self, key):
e = self._detect(key)
if e:
return e[key]
else:
return None # NOTICE !!

2つのメソッド __getitem__/get の本体を見ると、その違いは else に続く箇所だけだと分かります。そこで、これらの異なるコードの断片から共通する構造を抽出して、それを再利用可能にするために、リファクタリングを履行します。
《Note》組み込み型 dict で規定された get では、第2引数に、キーが存在しない場合の規定値を指定できます。ここで紹介したものは、その暫定版です。この話題については、別の記事で紹介します。

[Python]ある解決法

リファクタリングを履行すると、次のように、コードの見通しが良くなり、その保守も容易になります。



        • -

共通する処理(テンプレート)_toget と、クラスごとに固有の処理 _getitem/_get とを分割統治します。


class eXdict:
def _toget(self, key, func):
e = self._detect(key)
if e:
return self._valueItem(e, key)
else:
return eval("self._%s(key)"%func)

補助関数 _toget では、前述した補助関数 _detect を利用して、指定したキー key を含む項目 e を獲得します。if に続く条件式 e を満たすなら、該当する項目が存在するので、補助関数 _valueItem を利用して、指定したキー key に対応する値をリターン値とします。それが存在しないなら、引数 func が参照する関数オブジェクトに、その後処理を委ねます。


def _getitem(self, key): raise KeyError, key

メソッド __getitem__ に固有の処理を記述します。指定したキー key が存在しないなら、例外 KeyError を生成します。


def _get (self, key): return None

メソッド get に固有の処理を記述します。指定したキー key が存在しないなら、None をリターン値とします。


# cz_08.py -------------------------------------------- after ---
class eXdict:
def __getitem__(self, key):
return self._toget(key, "getitem")
def get(self, key):
return self._toget(key, "get")

リファクタリング後のメソッド __getitem__/get では、先の補助関数 _toget の引数に、各処理を識別する "getitem"/"get" を指定するだけです。


Previous|7/10|Next