Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
271 views
in Technique[技术] by (71.8m points)

.net - 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#?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...