在C#中实例化一个python类

我已经写了一个python类,我想通过IronPython包装到.net程序集中,并在C#应用程序中实例化。 我已经将类迁移到IronPython,创build了一个库程序集并引用它。 现在,我怎样才能真正得到这个类的一个实例呢?

class级看起来(部分)如下:

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

我在C#中编写的testing存根是:

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

为了在C#中实例化这个类,我需要做些什么?

IronPython类不是 .NET类。 它们是Python元类IronPython.Runtime.Types.PythonType的实例。 这是因为Python类是dynamic的,支持在运行时添加和删除方法,这是.NET类无法做到的。

要在C#中使用Python类,您将需要使用ObjectOperations类。 这个类允许你在语言本身的语义上对pythontypes和实例进行操作。 例如它在适当时使用魔术方法,自动将整数提升为长整型等。通过查看源代码或使用reflection器,可以了解关于ObjectOperations的更多信息。

这是一个例子。 Calculator.py包含一个简单的类:

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

你可以像你这样使用.NET 4.0以前的C#代码:

 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) 

您将需要引用程序集IronPython.dll,Microsoft.Scripting和Microsoft.Scripting.Core。

使用新的dynamictypes,C#4使这更容易。

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

如果您使用Visual Studio 2010或更高版本的NuGet支持,只需执行此操作即可下载并引用相应的库。

 Install-Package IronPython 

现在.NET 4.0已经发布并且具有dynamictypes,这个例子应该被更新。 使用与m-sharp的原始答案相同的python文件:

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

这里是你如何使用.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); 

同样,您需要添加对IronPython.dll和Microsoft.Scripting的引用。

如您所见,源文件的初始设置和创build是相同的。

但是一旦源码成功执行,由于新的“dynamic”关键字,使用python函数更容易。

我正在更新上面的Clever Human提供的编译IronPython类(dll)而不是.py文件中的IronPython源代码的例子。

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

新的dynamictypes的C#4.0代码如下:

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

参考文献:

  1. 使用.NET / CSharp IP 2.6编译的Python类
  2. 静态编译IronPython脚本

我search了高低,恐怕似乎没有太多有关这方面的信息。 我非常肯定,没有人devise出一种你想要的干净方式来做到这一点。

我认为这是一个问题的主要原因是,为了在你的C#应用​​程序中看到PokerCardtypes,你必须将你的Python代码编译成IL。 我不相信在那里有任何Python -> IL编译器。