Question

J'ai écrit une classe en python que je veux envelopper dans un ensemble de .net via IronPython et instancier dans une application C #. J'ai migré la classe à IronPython, créé un ensemble bibliothèque et référencé. Maintenant, comment puis-je en fait une instance de cette classe?

Les regards de la classe (en partie) comme ceci:

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

    def __init__(self, cardName):

Le talon de test je l'ai écrit en C # est:

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

Que dois-je faire pour instancier cette classe en C #?

Était-ce utile?

La solution

les classes IronPython sont pas .NET classes. Ce sont des cas de IronPython.Runtime.Types.PythonType qui est le métaclasse Python. Ceci est parce que les classes Python sont plus dynamiques et le soutien et la suppression des méthodes lors de l'exécution, les choses que vous ne pouvez pas faire avec des classes .NET.

Pour utiliser les classes Python en C #, vous devrez utiliser la classe ObjectOperations. Cette classe vous permet de faire fonctionner sur les types de python et les instances dans la sémantique de la langue elle-même. par exemple. il utilise les méthodes magiques lorsque l'auto-approprié favorise, entiers des positions longues etc. Vous pouvez en savoir plus sur ObjectOperations en regardant la source ou à l'aide réflecteur.

Voici un exemple. Calculator.py contient une classe simple:

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

Vous pouvez l'utiliser à partir de votre pré 4.0 .NET C # code comme ceci:

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)

Vous devrez référencer les assemblées IronPython.dll, Microsoft.Scripting et Microsoft.Scripting.Core.

C # 4 a fait ce beaucoup plus facile avec le nouveau type dynamique.

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

Si vous utilisez Visual Studio 2010 ou plus tard, avec le soutien NuGet il suffit d'exécuter ce pour télécharger et référencer les bibliothèques appropriées.

Install-Package IronPython

Autres conseils

Maintenant que .Net 4.0 est sorti et a le type dynamique, cet exemple doit être mis à jour. En utilisant le même fichier python comme réponse originale de m-sharp:

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

Voici comment vous appeler en utilisant .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);          

Encore une fois, vous devez ajouter des références à IronPython.dll et Microsoft.Scripting.

Comme vous pouvez le voir, le réglage initial et création du fichier source est le même.

Mais une fois que la source est exécutée avec succès, en collaboration avec les fonctions de python est beaucoup plus facile grâce au nouveau mot-clé « dynamique ».

Je mets à jour l'exemple ci-dessus fournies par Clever humaine pour les classes IronPython compilées (dll) au lieu du code source IronPython dans un fichier .py.

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

Code C # 4.0 avec le nouveau type dynamique est la suivante:

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

Références:

  1. En utilisant Compilé classes Python de .NET / CSharp IP 2.6
  2. Compilation statique des scripts IronPython

J'ai cherché haut et bas et je crains qu'il ne semble pas y avoir beaucoup d'informations se rapportant à ce sujet. Je suis à peu près certain que personne n'a trouvé un moyen de le faire de la manière propre que vous le souhaitez.

La principale raison pour laquelle je pense que cela est un problème est que pour voir le type de PokerCard dans votre application C # vous devez compiler votre code Python pour IL. Je ne crois pas qu'il y ait des compilateurs Python->IL là-bas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top