スをインスタンス化pythonのクラスのクライアントまで、フルのC#
-
06-09-2019 - |
質問
長々と書きましたが、クラスのpythonしたいラップへ。純組み立てによIronPython、インスタンスを生成にC#アプリ。私は移行のクラスIronPythonは、図書館組立-参照されます。今、どうやって実際のインスタンスを取得した。
クラスの見(一部)のようになります:
class PokerCard:
"A card for playing poker, immutable and unique."
def __init__(self, cardName):
この試験はスタブが書いたクライアントまで、フルのC#です:
using System;
namespace pokerapp
{
class Program
{
static void Main(string[] args)
{
var card = new PokerCard(); // I also tried new PokerCard("Ah")
Console.WriteLine(card.ToString());
Console.ReadLine();
}
}
}
何をしていないため、このクラスのインスタンスを生成クライアントまで、フルのC#?
解決
IronPythonのクラスです。のないの.NETクラス。彼らは、PythonのメタクラスであるIronPython.Runtime.Types.PythonTypeのインスタンスです。 Pythonのクラスを使用すると、.NETクラスで行うことができない、物事は動的であり、実行時にメソッドの追加と削除をサポートするためです。
あなたはObjectOperationsクラスを使用する必要がありますC#でPythonのクラスを使用します。このクラスを使用すると、言語自体の意味でのpythonの種類とインスタンス上で動作させることができます。例えばそれは、などlong型の整数を適切な自動-促進マジックメソッドを使用しますが、ソースを見ているかの反射を利用してObjectOperationsについての詳細を調べることができます。
ここでは一例です。 Calculator.pyは、単純なクラスが含まれています:
class Calculator(object):
def add(self, a, b):
return a + b
あなたは、このようなあなたの前.NET 4.0 C#コードからそれを使用することができます:
ScriptEngine engine = Python.CreateEngine();
ScriptSource source = engine.CreateScriptSourceFromFile("Calculator.py");
ScriptScope scope = engine.CreateScope();
ObjectOperations op = engine.Operations;
source.Execute(scope); // class object created
object klaz = scope.GetVariable("Calculator"); // get the class object
object instance = op.Call(klaz); // create the instance
object method = op.GetMember(instance, "add"); // get a method
int result = (int)op.Call(method, 4, 5); // call method and get result (9)
あなたはアセンブリIronPython.dll、Microsoft.ScriptingとMicrosoft.Scripting.Coreを参照する必要があります。
C#4は、の新しいの動的な型で、これは非常に簡単になります。
ScriptEngine engine = Python.CreateEngine();
ScriptSource source = engine.CreateScriptSourceFromFile("Calculator.py");
ScriptScope scope = engine.CreateScope();
source.Execute(scope);
dynamic Calculator = scope.GetVariable("Calculator");
dynamic calc = Calculator();
int result = calc.add(4, 5);
あなたはNuGetのサポートでのVisual Studio 2010以降を使用している場合は、単に適切なライブラリをダウンロードして参照するために、これを実行します。
Install-Package IronPython
他のヒント
さて、この例では、更新する必要があります。 M-シャープのオリジナルの答えと同じのpythonファイルを使用します:
class Calculator(object):
def add(self, a, b):
return a + b
ここでは、.NET 4.0を使用してそれを呼び出す方法です。
string scriptPath = "Calculator.py";
ScriptEngine engine = Python.CreateEngine();
engine.SetSearchPaths(new string[] {"Path to your lib's here. EG:", "C:\\Program Files (x86)\\IronPython 2.7.1\\Lib"});
ScriptSource source = engine.CreateScriptSourceFromFile(scriptPath);
ScriptScope scope = engine.CreateScope();
ObjectOperations op = engine.Operations;
source.Execute(scope);
dynamic Calculator = scope.GetVariable("Calculator");
dynamic calc = Calculator();
return calc.add(x,y);
ここでも、あなたはIronPython.dllとMicrosoft.Scriptingへの参照を追加する必要があります。
あなたが見ることができるように、初期設定まで、ソースファイルの作成は同じです。
ソースが正常に実行されたら、しかし、新しい「ダイナミック」のキーワードにはるかに簡単おかげでPythonの関数とされる作業ます。
私の例では、より賢い人のためのデIronPythonクラス(dll)の代わりにIronPythonソースコード。pyファイルです。
# Compile IronPython calculator class to a dll
clr.CompileModules("calculator.dll", "calculator.py")
C#4.0コードに新しいダイナミックタイプとして
// IRONPYTHONPATH environment variable is not required. Core ironpython dll paths should be part of operating system path.
ScriptEngine pyEngine = Python.CreateEngine();
Assembly myclass = Assembly.LoadFile(Path.GetFullPath("calculator.dll"));
pyEngine.Runtime.LoadAssembly(myclass);
ScriptScope pyScope = pyEngine.Runtime.ImportModule("calculator");
dynamic Calculator = pyScope.GetVariable("Calculator");
dynamic calc = Calculator();
int result = calc.add(4, 5);
参考文献:
私はハイとローで検索しましたし、私はこれに関連する多くの情報があるように思われないことを恐れています。私は、誰もあなたが好きだろうとクリーンな方法でこれを行う方法を考案していないことはかなり確信しています。
私は、これが問題だと思う主な理由は、あなたのC#アプリケーションでPokerCard
の種類を見るためにあなたがILにあなたのPythonコードをコンパイルしなければならないということです。私はそこに任意のPython->
ILコンパイラがあることを信じていません。