Python.use(better, follow=”K&R”) リファクタリング 7/10
《Previous|7/10|Next》
Python.use(better, follow=”K&R”) # for novice 《記事一覧》
リファクタリング:メソッド固有の処理
[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" を指定するだけです。