我在python中编写了一个类,我希望通过IronPython将其包装到.net程序集中并在C#应用程序中实例化.我已经将类迁移到IronPython,创建了一个库程序集并引用它.现在,我如何实际获得该类的实例?
该类看起来(部分)像这样:
class PokerCard: "A card for playing poker, immutable and unique." def __init__(self, cardName):
我在C#中编写的测试存根是:
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类.它们是IronPython.Runtime.Types.PythonType的实例,它是Python元类.这是因为Python类是动态的,并且支持在运行时添加和删除方法,这是.NET类无法做到的.
要在C#中使用Python类,您需要使用ObjectOperations类.该类允许您在语言本身的语义中操作python类型和实例.例如,它在适当时使用魔术方法,自动将整数提升为long等.您可以通过查看源或使用反射器来了解有关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.
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已经发布并具有动态类型,因此应该更新此示例.使用与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的引用.
如您所见,源文件的初始设置和创建是相同的.
但是一旦源成功执行,由于新的"动态"关键字,使用python函数会更容易.