Python WorkshopのHands-onサンプル


Python Workshop the Edge 2007でIronPythonのHands-onを担当したのは前回の記事で説明しました。このHands-on用に公開したサンプルにファイルムーバーサンプルがあります。このサンプルを動作させると以下のようなWindows Formsが起動します。
FileMover


このサンプルの特徴は以下のようなものです。



  • FileSystemWatcherクラスを使ってイベント監視
  • 作成したファイルを移動する
  • 移動した結果をリストボックスへ表示する

回答サンプルに「filemover2.py」があります。この回答サンプルの特徴は、以下のようなクラスを持つことです。



  • Appクラス:Windows.Forms.Formを継承したクラス
  • Watcherクラス:FileSystemWatcherの制御を行うクラス

FileSystemWatcherクラスの特徴は、ファイルシステムjに対する変更をイベントハンドラで監視することができることです。このためファイル作成イベント(Created)ハンドラのなかで、作成されたファイルを指定したフォルダへ移動しています。ここで1つの問題があります。それはフォームのリストボックスへ文字列を追加することです。C#やVBなどの.NET対応の言語をご存じの方であれば、フォームのメソッドをInvokeしなければいけないというのがピンと来ると思います。そうなんです、これを実現するにはデリゲートを使わないといけないのです。何故なら、以下の理由があるからです。



  • FileSystemWatcherのイベントハンドラは、スレッドプールから割り当てられるため、フォームのスレッドとは異なるスレッドに存在する。
  • フォームのコントロールを操作するには、デリゲートを使ってInvokeしなければならない(異なるスレッドからはコントロールを操作できない)。

これをIronPythonでどのように実現しようかと、少し悩みました。何故なら、IronPythonではデリゲートの型を定義できないからです(方法が無くはありませんが、少し面倒です)。少しだけ考えた結果、以下のような記述をしました。

#Wacherクラス内のmovefileメソッドです
def movefile(self, filename):
”’ ファイルの移動を行う ”’

# フォームのメソッドへInvoke(delegate)
# 変数outは、フォームのインスタンスを持つ
self.out.output(filename)


#Appクラス内のoutputメソッドです
def output(self, msg):
”’ ファイル移動メッセージの委譲処理 ”’
# Watcherクラスのイベントハンドラから呼ばれます
self.lb1.Items.Add(msg + u”を移動しました”)

 


シンプルにAppクラス内のメソッドを呼び出しているだけです。C#などではAppクラス内でDelegateのインスタンスを作成して、Invokeしなければなりません。何故、このような記述で実現できたかたと言うと、IronPythonの実装ではメソッド呼び出しをデリゲートに委譲しているからです。IronPythonのソースコードを見て、このことを知っていたのでこのような記述を思いついたのです。


これは私がIronPythonを気に入っている理由の一つでもあります。同じようにデリゲートをPowerShellで呼び出そうとすると中々と込み入った細工をする必要があります(PowerShell標準でデリゲート呼び出しをサポートしていないためです)。


このような特徴がIronPythonにありますので、DLRでも同じような特徴を持つことが考えられます。まだまだDLRは仕様が固まっていませんが、IronPython2.0A2では問題なくfilemover.2pyを実行することができました。

Comments (0)

Skip to main content