Frage

Ich habe eine Klasse in Python geschrieben, dass ich in eine .NET-Assembly über Ironpython wickeln will und in einer C # Anwendung instanziiert. Ich habe die Klasse zu Ironpython migriert, erstellt eine Bibliothek Montage und verwiesen. Nun, wie kann ich eigentlich eine Instanz dieser Klasse?

Die Klasse aussieht (teilweise) wie folgt aus:

class PokerCard:
    "A card for playing poker, immutable and unique."

    def __init__(self, cardName):

Der Test Stummel I in C # geschrieben ist:

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

Was muss ich tun, um diese Klasse in C # zu instanziiert?

War es hilfreich?

Lösung

Ironpython-Klassen sind nicht .NET-Klassen. Sie sind Instanzen von IronPython.Runtime.Types.PythonType, die der Python Metaklasse ist. Dies liegt daran, Python-Klassen sind dynamisch und Hinzufügen und Entfernen von Methoden zur Laufzeit unterstützen, Dinge, die Sie nicht mit .NET-Klassen tun.

Python-Klassen in C # zu verwenden, müssen Sie die ObjectOperations Klasse verwenden. Diese Klasse ermöglicht es Ihnen, auf Python-Typen und Instanzen in der Semantik der Sprache selbst zu bedienen. z.B. es die magischen Methoden verwendet, wenn angemessen, ganze Zahlen longs Auto-fördert usw. Sie können an der Quelle, indem Sie mehr über ObjectOperations erfahren oder Reflektor.

Hier ist ein Beispiel. Calculator.py enthält eine einfache Klasse:

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

Sie können es von Ihrem Pre .NET 4.0 C # Code wie folgt:

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)

Sie müssen die Baugruppen IronPython.dll, Microsoft.Scripting und Microsoft.Scripting.Core verweisen.

C # 4 machte diese viel einfacher, mit dem neuen dynamischem Typ.

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

Wenn Sie Visual Studio 2010 oder später mit NuGet Unterstützung einfach ausführen diese herunterladen und verweisen auf die entsprechenden Bibliotheken verwenden.

Install-Package IronPython

Andere Tipps

Nun, da .Net 4.0 freigegeben und hat den dynamischen Typen, sollte dieses Beispiel aktualisiert werden. Unter Verwendung der gleichen Python-Datei, wie in m-scharfe ursprüngliche Antwort der:

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

Hier ist, wie Sie es mit .NET 4.0 nennen würden:

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

Auch hier müssen Sie Verweise auf IronPython.dll und Microsoft.Scripting hinzuzufügen.

Wie Sie sehen können, die Ersteinrichtung und Erstellen der Quelldatei ist das gleiche.

Aber sobald die Quelle erfolgreich ausgeführt wird, die Arbeit mit den Python-Funktionen ist viel einfacher, dank der neuen „dynamischen“ Schlüsselwort.

Ich bin Aktualisierung des obigen Beispiels von Clever Menschen vorgesehen zusammengestellt Ironpython-Klassen (dll) anstelle von Ironpython-Quellcode in einer Py-Datei.

# Compile IronPython calculator class to a dll
clr.CompileModules("calculator.dll", "calculator.py")

C # 4.0-Code mit dem neuen dynamischen Typ ist wie folgt:

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

Referenzen:

  1. Verwendung Zusammengestellt Python Klassen von .NET / CSharp IP 2.6
  2. Static Compilation von Ironpython-Skripte

Ich habe hohe und niedrige gesucht und ich habe Angst, dass es nicht viele Informationen in Bezug auf dies zu sein scheint. Ich bin ziemlich sicher, dass niemand einen Weg, um dies in der sauberen Art und Weise zu tun, entwickelt hat, dass Sie möchten.

Der Hauptgrund, warum ich denke, dass das ein Problem ist, ist, dass Sie Ihren Python-Code zu IL kompilieren würden, um den PokerCard Typen in C # Anwendung sehen müssen. Ich glaube nicht, dass es irgendwelche Python->IL Compiler gibt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top