IronPythonでプログラミング可能なCONFIGファイルを実装する
はじめに
IronPythonを使えば、CONFIGファイルで自由にプログラミング可能なアプリケーションを、実装できる。本エントリでは、その方法を簡単に紹介する。
完成したCONFIGファイルのイメージ
「'hoge' + 'fuga'」とある部分が、Pythonのコードだ。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" > <section name="IronPythonSample.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> </sectionGroup> </configSections> <applicationSettings> <IronPythonSample.Properties.Settings> <setting name="PythonCode" serializeAs="String"> <value>'hoge' + 'fuga'</value> </setting> </IronPythonSample.Properties.Settings> </applicationSettings> </configuration>
IronPythonとは
インターネット上で簡単に調べられるので、ここでは詳細を述べないが、キーワードを挙げる。
- .NET Framework上で動作
- スクリプト言語Pythonの実行環境
- フリー:Apache License 2.0
- Dynamic Language Runtime(DLR)上で動作
- 米Microsoft社のオープンソースプロジェクト
DLRとは
「IronPythonとは」で触れたDLRとは何か。これもインターネット上で簡単に調べられるので、ここでは詳細を述べないが、キーワードを挙げる。
- 動的言語を.NET Framework上に実装するための基盤
- フリー:Apache License 2.0
- 米Microsoft社のオープンソースプロジェクト
- IronPython以外にも、次のような実装がある
- Rubyの実装「IronRuby」(安定版あり)
- Luaの実装「Nua」(開発中)
- JavaScriptの実装「IronJS」(状態未調査)
- JavaScriptの実装「Javascript DLR Engine」*1(開発中)
つまり、次のようなイメージだ*2。
IronPython | IronRuby | (様々な実装) |
DLR | ||
CLR |
前置きはここまでにして、実際に実装していく。
IronPythonをインストール
IronPythonのDownloadsページに行き、「IronPython <バージョン> for .NET <.NETのバージョン>.msi」をダウンロード。あとはインストールでOKだ。ここでは、「IronPython 2.6.1 for .NET 2.0 SP1.msi」をインストールしたものとする。
ホストアプリケーションを作成
IronPythonをホストする.NETアプリケーションを作成する。.NETからIronPythonを使うのに必要なのは、IronPythonのアセンブリへの参照の追加だけだ。IronPythonをインストールしたディレクトリ直下に、いくつかのDLLファイルがあるので、それらのうち必要なものを、アプリケーションから参照する。
余談だが、どのDLLファイルが必要なのかが、私には分からない。インターネットで調べてみると、情報があるにはあったのだが、確認が持てなかった。と言うのも、どうやらIronPythonのバージョンによってDLLファイルの構成が違うようで、使おうとしているバージョンではどうなのかが、はっきりしないのだ。そのため今回は、上記ディレクトリ内に7つもあるDLLファイルを、全て参照した。
CONFIGファイルを作成
文字列の値を取る設定項目をCONFIGファイルに設け(どういう方法でも良い)、その値をPythonコードにする。私の場合、Visual Studioでエディターが使えるSettings.settingsファイルを使って、「完成したCONFIGファイルのイメージ」のようなものを作った。
Pythonコードを実行
いよいよPythonコードを実行する。コード(C# 3.0以降)は次のようになる。
var code = Settings.Default.PythonCode; // 設定値を取得 _pythonCodeTextBox.Text = code; var result = Python.CreateEngine().Execute(code); // コードを実行 _resultTextBox.Text = Convert.ToString(result);
ポイントは次の部分だ。
Python.CreateEngine().Execute(code)
注意:パフォーマンス
アプリケーションで実際にIronPython(など、DLR上で動作するライブラリ)を使う場合、パフォーマンスに要注意だ。それを使わないアプリケーションに比べパフォーマンスが遅くなる要因を、以下に挙げる。
実際に私が割と本格的なアプリケーションを作った経験から言うと、IronPythonを使うことで、パフォーマンスは劇的に悪化した感じがある。実際にはそのアプリケーションのIronPythonを使わないバージョンを作ったわけではないので、正確なことは言えないが、感覚的に明らかだった。
アプリケーション開発者にできることは、Pythonコードの不要なコンパイルを避けることぐたいだろうか。これはDLRの仕様なのだが、CompiledCodeクラスというのがあって、コードのコンパイル結果をキャッシュできる。何度も実行するコードがあるなら、そのコンパイル結果をキャッシュすべきだろう。
注意:セキュリティ
本エントリでは書ききれなかったが、IronPythonの大きな特長の1つが、.NET Frameworkのクラスを全て利用可能な点だ。つまりこれは、Pythonコードから何でもできることを意味する。例えば、CONFIGファイルを記述しさえすれば、本エントリで作成したアプリケーションから、スパムメールを送信することさえできてしまうはずだ。これは、重大なセキュリティリスクとなり得る。
この問題にどう対処するのか。私は実際に検証したわけではないので責任は持てないのだが、コードアクセスセキュリティがキーワードなのではないか。こう私が考えた理由は単純で、今回のサンプルアプリケーションでも使ったCreateEngineメソッドに、AppDomainを引数に取るオーバーロードがあるからだ。例えばネットワークに接続できないよう設定したAppDomainを渡すことで、Pythonコードからスパムメールを送ることはできなくなるのではないか。私は今のところ、この真否を確かめられていない*3。
まとめ
IronPythonを使えば、コードをビルドし直すことなく動的に動作を変更できるアプリケーションを、実装できることが分かった。ただしその使用には、パフォーマンス、およびセキュリティという非常に重要な点で、注意が必要でもある。つまり、「柔軟性と堅牢性のトレードオフ」を見極めることが、重要だ。