Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Instantiating a python class in C#

I've written a class in python that I want to wrap into a .net assembly via IronPython and instantiate in a C# application. I've migrated the class to IronPython, created a library assembly and referenced it. Now, how do I actually get an instance of that class?

The class looks (partially) like this:

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

The test stub I wrote in C# is:

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

What do I have to do in order to instantiate this class in C#?

like image 450
Yes - that Jake. Avatar asked Feb 23 '09 20:02

Yes - that Jake.


People also ask

How do you instantiate a class in Python?

Instantiating a class in Python is simple. To instantiate a class, we simply call the class as if it were a function, passing the arguments that the __init__ method defines. The return value will be the newly created object.

How do you instantiate a class?

Instantiating a ClassThe new operator requires a single, postfix argument: a call to a constructor. The name of the constructor provides the name of the class to instantiate. The constructor initializes the new object. The new operator returns a reference to the object it created.

Why do we need to instantiate a class Python?

Class constructors are a fundamental part of object-oriented programming in Python. They allow you to create and properly initialize objects of a given class, making those objects ready to use.

How do you call a class in Python C#?

To use Python classes in C# you will need to use the ObjectOperations class. This class allows you to operate on python types and instances in the semantics of the language itself. e.g. it uses the magic methods when appropriate, auto-promotes integers to longs etc.


2 Answers

IronPython classes are not .NET classes. They are instances of IronPython.Runtime.Types.PythonType which is the Python metaclass. This is because Python classes are dynamic and support addition and removal of methods at runtime, things you cannot do with .NET classes.

To use Python classes in C# you will need to use the ObjectOperations class. This class allows you to operate on python types and instances in the semantics of the language itself. e.g. it uses the magic methods when appropriate, auto-promotes integers to longs etc. You can find out more about ObjectOperations by looking at the source or using reflector.

Here is an example. Calculator.py contains a simple class:

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

You can use it from your pre .NET 4.0 C# code like this:

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) 

You will need to reference the assemblies IronPython.dll, Microsoft.Scripting and Microsoft.Scripting.Core.

C# 4 made this much easier with the new dynamic type.

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

If you are using Visual Studio 2010 or later with NuGet support simply execute this to download and reference the appropriate libraries.

Install-Package IronPython 
like image 134
m-sharp Avatar answered Oct 05 '22 02:10

m-sharp


Now that .Net 4.0 is released and has the dynamic type, this example should be updated. Using the same python file as in m-sharp's original answer:

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

Here is how you would call it using .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);           

Again, you need to add references to IronPython.dll and Microsoft.Scripting.

As you can see, the initial setting up and creating of the source file is the same.

But once the source is succesfully executed, working with the python functions is far easier thanks to the new "dynamic" keyword.

like image 41
CleverPatrick Avatar answered Oct 05 '22 02:10

CleverPatrick