44

IronPythonを介して.netアセンブリにラップし、C#アプリケーションでインスタンス化するクラスをPythonで作成しました。クラスを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#でインスタンス化するには、何をする必要がありますか?

4

4 に答える 4

56

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

C# で Python クラスを使用するには、ObjectOperations クラスを使用する必要があります。このクラスを使用すると、言語自体のセマンティクスで 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
于 2009-02-23T22:14:43.380 に答える
32

.Net 4.0がリリースされ、動的タイプになっているので、この例を更新する必要があります。m-sharpの元の回答と同じPythonファイルを使用する:

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

.Net4.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関数の操作がはるかに簡単になります。

于 2010-04-27T15:39:13.937 に答える
0

.py ファイルの IronPython ソース コードではなく、コンパイルされた IronPython クラス (dll) に対して 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. .NET/CSharp IP 2.6 からコンパイルされた Python クラスを使用する
  2. IronPython スクリプトの静的コンパイル
于 2013-06-11T14:12:29.587 に答える
-4

私は高低を検索しましたが、これに関する情報はあまりないようです. あなたが望むようにきれいな方法でこれを行う方法を誰も考案していないことはほぼ確実です.

これが問題だと思う主な理由はPokerCard、C# アプリケーションで型を確認するには、Python コードを IL にコンパイルする必要があるからです。->そこに Python IL コンパイラがあるとは思えません。

于 2009-02-23T21:09:38.887 に答える