subclases resueltos programacion privados poo orientada objetos importar herencia ejercicios ejemplos clases clase atributos c# .net python ironpython cross-language

c# - resueltos - programacion orientada a objetos python ejemplos pdf



Hacer una instancia de una clase de python en C# (4)

He buscado alto y bajo y me temo que no parece haber mucha información relacionada con esto. Estoy casi seguro de que nadie ha ideado una forma de hacer esto de la manera más limpia que le gustaría.

La razón principal por la que creo que esto es un problema es que para ver el tipo de PokerCard en su aplicación C # tendrías que compilar tu código Python para IL. No creo que haya ningún compilador de Python -> IL.

Escribí una clase en python que quiero envolver en un ensamblado .net a través de IronPython y crear instancias en una aplicación C #. Migré la clase a IronPython, creé un conjunto de biblioteca y lo referenciaba. Ahora, ¿cómo obtengo una instancia de esa clase?

La clase se ve (parcialmente) así:

class PokerCard: "A card for playing poker, immutable and unique." def __init__(self, cardName):

El talón de prueba que escribí en C # es:

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

¿Qué tengo que hacer para crear una instancia de esta clase en C #?


Las clases de IronPython no son clases de .NET. Son instancias de IronPython.Runtime.Types.PythonType que es la metaclase de Python. Esto se debe a que las clases de Python son dinámicas y admiten la adición y eliminación de métodos en tiempo de ejecución, cosas que no se pueden hacer con las clases de .NET.

Para usar las clases de Python en C # necesitarás usar la clase ObjectOperations. Esta clase le permite operar en tipos e instancias de Python en la semántica del lenguaje en sí. por ejemplo, utiliza los métodos mágicos cuando es apropiado, promueve automáticamente enteros a largos, etc. Puede encontrar más información sobre ObjectOperations mirando la fuente o utilizando el reflector.

Aquí hay un ejemplo. Calculator.py contiene una clase simple:

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

Puede usarlo desde su código pre .NET 4.0 C # de la siguiente manera:

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)

Deberá hacer referencia a los ensamblados IronPython.dll, Microsoft.Scripting y Microsoft.Scripting.Core.

C # 4 hizo esto mucho más fácil con el nuevo tipo dinámico.

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 está utilizando Visual Studio 2010 o posterior con soporte NuGet, simplemente ejecútelo para descargar y consultar las bibliotecas apropiadas.

Install-Package IronPython


Ahora que se lanza .Net 4.0 y tiene el tipo dinámico, este ejemplo debe actualizarse. Usando el mismo archivo python que en la respuesta original de m-sharp:

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

Así es como lo llamarías usando .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);

De nuevo, necesita agregar referencias a IronPython.dll y Microsoft.Scripting.

Como puede ver, la configuración inicial y la creación del archivo fuente es la misma.

Pero una vez que la fuente se ejecuta con éxito, trabajar con las funciones de python es mucho más fácil gracias a la nueva palabra clave "dinámica".


Estoy actualizando el ejemplo anterior proporcionado por Clever Human para compilar las clases de IronPython (dll) en lugar del código fuente de IronPython en un archivo .py.

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

El código de C # 4.0 con el nuevo tipo dinámico es el siguiente:

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

Referencias

  1. Uso de clases compiladas de Python desde .NET / CSharp IP 2.6
  2. Compilación estática de scripts IronPython