web-dev-qa-db-ja.com

C#アプリから(Iron)Pythonコードを呼び出すにはどうすればよいですか?

Pythonコード、C#からIronPythonを使用して呼び出す方法はありますか?

51
David Thielen

プロセスは簡単です。特に、C#/。NET 4アプリケーションでは、dynamicタイプの使用により動的言語のサポートが改善されています。ただし、最終的には、アプリケーション内で(Iron)Pythonコードをどのように使用するかによって異なります。常に_ipy.exe_を個別のプロセスとして実行し、ソースファイルを渡して実行できるようにすることができます。しかし、おそらくC#アプリケーションでHostにしたかったでしょう。それには多くのオプションがあります。

  1. _IronPython.dll_および_Microsoft.Scripting.dll_アセンブリへの参照を追加します。通常、これらは両方ともルートIronPythonインストールディレクトリにあります。

  2. ソースの先頭に_using IronPython.Hosting;_を追加し、Python.CreateEngine()を使用してIronPythonスクリプトエンジンのインスタンスを作成します。

  3. ここからいくつかのオプションがありますが、基本的にはScriptScopeまたはScriptSourceを作成し、dynamic変数として保存します。これにより、実行を選択したり、C#からスコープを操作したりすることができます。

オプション1:

CreateScope()を使用して空のScriptScopeを作成し、C#コードで直接使用しますが、Pythonソースで使用できます。これらは、インタプリタのインスタンス。

_dynamic scope = engine.CreateScope();
scope.Add = new Func<int, int, int>((x, y) => x + y);
Console.WriteLine(scope.Add(2, 3)); // prints 5
_

オプション2:

Execute()を使用して、文字列内のIronPythonコードを実行します。 ScriptScopeを渡すことができるオーバーロードを使用して、コードで定義された変数を保存または使用できます。

_var theScript = @"def PrintMessage():
    print 'This is a message!'

PrintMessage()
";

// execute the script
engine.Execute(theScript);

// execute and store variables in scope
engine.Execute(@"print Add(2, 3)", scope);
// uses the `Add()` function as defined earlier in the scope
_

オプション3:

ExecuteFile()を使用してIronPythonソースファイルを実行します。 ScriptScopeを渡すことができるオーバーロードを使用して、コードで定義された変数を保存または使用できます。

_// execute the script
engine.ExecuteFile(@"C:\path\to\script.py");

// execute and store variables in scope
engine.ExecuteFile(@"C:\path\to\script.py", scope);
// variables and functions defined in the scrip are added to the scope
scope.SomeFunction();
_

オプション4:

GetBuiltinModule()またはImportModule()拡張メソッドを使用して、上記モジュールで定義された変数を含むスコープを作成します。この方法でインポートされたモジュールは、検索パスで設定する必要があります。

_dynamic builtin = engine.GetBuiltinModule();
// you can store variables if you want
dynamic list = builtin.list;
dynamic itertools = engine.ImportModule("itertools");
var numbers = new[] { 1, 1, 2, 3, 6, 2, 2 };
Console.WriteLine(builtin.str(list(itertools.chain(numbers, "foobar"))));
// prints `[1, 1, 2, 3, 6, 2, 2, 'f', 'o', 'o', 'b', 'a', 'r']`

// to add to the search paths
var searchPaths = engine.GetSearchPaths();
searchPaths.Add(@"C:\path\to\modules");
engine.SetSearchPaths(searchPaths);

// import the module
dynamic myModule = engine.ImportModule("mymodule");
_

.NETプロジェクトで多くのホスティングを行うことができますPythonコード。C#は、そのギャップを簡単に埋めることができます。もちろん、_IronPython.Hosting_名前空間にあるクラスでできることは他にもありますが、これで十分です。

112
Jeff Mercado

関数を実行するには、Jeff Mercadoの応答のオプション3のように呼び出すことはできません(これは非常に便利です!しかし、少なくとも.NET 4.5では、このオプションはコンパイルされません)。 ScriptScope.GetVariableを使用して実際の関数を取得し、C#関数のように呼び出すことができます。次のように使用します。

C#コード:

var var1,var2=...
ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
engine.ExecuteFile(@"C:\test.py", scope);
dynamic testFunction = scope.GetVariable("test_func");
var result = testFunction(var1,var2);

Pythonコード:

def test_func(var1,var2):
    ...do something...

最終的にそれを理解するのにしばらくかかりましたが、それは非常に単純です。お役に立てれば :)

3
LiRoN