2009-02-23 11 views
40

PythonでIronPython経由で.netアセンブリにラップし、C#アプリケーションでインスタンス化するクラスを作成しました。クラスをIronPythonに移行し、ライブラリアセンブリを作成して参照しました。今、どのように実際にそのクラスのインスタンスを取得するのですか?このようなC#でのPythonクラスのインスタンス化

クラスのルックス(部分的に):私はC#で書いた

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(); 
     } 
    } 
} 

答えて

51

IronPythonクラスはではなく、 .NETクラスです。 PythonメタクラスであるIronPython.Runtime.Types.PythonTypeのインスタンスです。これは、Pythonクラスが動的であり、実行時にメソッドの追加や削除をサポートするためです。.NETクラスではできないことです。

C#でPythonクラスを使用するには、ObjectOperationsクラスを使用する必要があります。このクラスは、言語そのもののセマンティクスで、Pythonの型とインスタンスを操作することを可能にします。例えば必要に応じてマジックメソッドを使用し、整数をlongなどに自動的に昇格させます。ObjectOperationsの詳細については、ソースを参照するか、リフレクタを使用して調べることができます。

ここは例です。

class Calculator(object): 
    def add(self, a, b): 
     return a + b 

あなたはこのようなあなたの前.NET 4.0 C#コードからそれを使用することができます:あなたはアセンブリIronPython.dll、マイクロソフトを参照する必要があります

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) 

Calculator.pyは、単純なクラスが含まれています。スクリプティングと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 
+1

を私は持っていませんこれを編集する担当者しかし、Calculator.pyサンプルでは、​​最初の "def"はインデントされるべきです。 素晴らしい例ですが、非常に役立ちます。今度は.Net 4.0がリリースされました。更新された例を見るのは良いことです。 –

+5

同じCalculatorサンプルクラスを使用して.Net 4.0サンプルを追加しました。 –

+0

ありがとう、私はインデントを追加しました。 –

-4

私は高低を検索しましたが、これに関連する情報はあまりないと思われます。私は誰もあなたが望むようなきれいな方法でこれを行う方法を工夫していないことはかなり確信しています。

私はこれが問題だと主な理由は、あなたのC#アプリケーションでPokerCardタイプを見るためには、PythonコードをILにコンパイルする必要があるということです。私はPython -> ILコンパイラがあるとは思わない。

31

.Net 4.0がリリースされ、動的な種類があるので、この例は更新する必要があります。 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。

ご覧のとおり、ソースファイルの初期設定と作成は同じです。

しかし、いったんソースが正常に実行されると、新しい "dynamic"キーワードのおかげで、Python関数を使った作業がはるかに簡単になります。

+0

この例を追加してくれてありがとう! –

+0

これは本当に助けになりました! –

0

IronPythonのソースコードではなく、コンパイル済みのIronPythonクラス(dll)が.pyファイルにある場合、Clever Humanが提供する上記の例を更新しています。新しい動的な型を持つ

# 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); 

参考文献:

  1. Using Compiled Python Classes from .NET/CSharp IP 2.6
  2. Static Compilation of IronPython scripts
関連する問題