linuxBean14.04(169)Pythonでデザインパターン:Strategy

ラベル: , , ,
linuxBean14.04(165)faif/python-patternsでデザインパターンの学習の続きです。Pythonの適当な本をもっていないので、参考にする本はlinuxBean14.04(168)NetBeans8.0.2でJavaソースコードからUML図を出力するで使ったJavaのものです。

前の関連記事:linuxBean14.04(168)NetBeans8.0.2でJavaソースコードからUML図を出力する


Behavioral Patterns:Strategy 同じデータに対して選択可能な操作


behavioral/strategy.py

関数を引数に渡して、データに対する処理を変化させています。

LibreOffice5(39)ProtocolHandler Addon Javaのxcuファイルを出力するPythonスクリプトでも同じ手法を使いました。

step3createXCUs.pyではメソッドの引数の辞書に関数を入れてあるのでわかりにくいですが、やっていることは一緒です。

strategy.pyを図示化してみます。

linuxBean14.04(40)pycallgraphでPythonのコールグラフ:その1

linuxBean14.04(49)pyreverseでPythonコードからUML図を生成

これらpycallgraphとpyreverseを使うことにします。

いちいちAnacondaに切り替えるのは面倒なのでバージョンは落ちますば全部Synapticパッケージマネージャでインストールし直しました。

python-pycallgraph 1.0.1-1
graphviz 2.36.0-0ubuntu3.2

これでまずpycallgraphをstrategy.pyがあるディレクトリで実行しました。

pycallgraph graphviz strategy.py



strategy.pyと同じフォルダにpycallgraph.pngが出力されました。

pycallgraphはその名の通りUML図でなく、コールグラフを出力するものなので、ソースの構造を知るのにはあまり役立ちません。

pylint 1.1.0-1

次にpylint付属のpyreverseを実行します。

pyreverse -o png -p strategy strategy.py


strategy.pyと同じフォルダにclasses_strategy.pngが出力されました。

これはUML図が出力されましたが、一つのクラスが表示されるだけです。

Javaと違ってPythonではUML図は必ずしも参考になりませんね。

headfirst.designpatterns.strategyをpythonにする


linuxBean14.04(168)NetBeans8.0.2でJavaソースコードからUML図を出力するHead-First-Design-Patterns/src/headfirst/designpatterns/strategyをPythonで同じようにしてみます。

The Lack of_ Design Patterns in Python Presentation.pdf 
(Strategyパターンについては24枚目)

design-patterns.pdf
(Strategyパターンについては16枚目)

JavaのインターフェイスをPythonをどう実装するのか調べているうちにこれらの資料を見つけました、、、

PythonはJavaと違って関数が第一級オブジェクトなのでそれを活かせばデザインパターンを暗黙的に使っていることになるようです。

python-patterns/strategy_headfirst.py at 1cd2b4311c6916cb3c151c84985590cbe940d113 · p--q/python-patterns

ということでインターフェイスについては難しく考えずに単に関数を渡すだけで処理しました。

pyreverse -o png -p strategy_headfirst strategy_headfirst.py


うーん、クラス図をみても普通で別にデザインパターンと言えるほどのものは何もありませんね。

ちなみにプロパティに代入ではなく、関数の引数として関数を渡すときは関数のデフォルトの引数をstrategy.pyのようにselfにしておかないといけないので、単に代入するだけの方がよいと思います。

strategy.pyのtypes.MethodType()で何をしているのか調べたところPython Tips:特異メソッドを作りたい - Life with Pythonに解説を見つけましたがよく理解できませんでした。
(2017.5.4追記。types.MethodType()は第1引数に関数、第2引数に第1引数の関数にバインドさせるオブジェクトを指定するものとわかりました。linuxBean14.04(170)Pythonのデスクリプタの学習を少し参照。)

Adding methods dynamically in Pythonにも解説があります。

参考にしたサイト


PowerPoint Presentation - _The Lack of_ Design Patterns in Python Presentation.pdf
Pythonの関数は第一級オブジェクトなので言語仕様に埋蔵されているパターンが多数あるとの解説。

design-patterns.pdf
Lispによる同様の解説、、、上記の元ネタ。

Python Tips:特異メソッドを作りたい - Life with Python
types.MethodType()の解説。

Adding methods dynamically in Python
types.MethodType()の解説。

次の関連記事:linuxBean14.04(170)Pythonのデスクリプタの学習を少し

PR

0 件のコメント:

コメントを投稿