代码之家  ›  专栏  ›  技术社区  ›  Yes - that Jake.

在C中实例化python类#

  •  42
  • Yes - that Jake.  · 技术社区  · 15 年前

    我已经用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中实例化这个类,我需要做什么?

    4 回复  |  直到 11 年前
        1
  •  55
  •   m-sharp    12 年前

    Ironpython类是 NET类。它们是Ironpython.runtime.types.pythontype的实例,后者是python元类。这是因为Python类是动态的,并且支持在运行时添加和删除方法,而这是您不能用.NET类做的。

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

    下面是一个例子。calculator.py包含一个简单类:

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

    您可以从.NET 4.0之前的代码中使用它,如下所示:

    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
    
        2
  •  31
  •   Athari    11 年前

    既然.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函数就更容易了,这要归功于新的“dynamic”关键字。

        3
  •  0
  •   bhadra    11 年前

    我正在更新聪明人为编译后的Ironpython类(dll)提供的上述示例,而不是.py文件中的Ironpython源代码。

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

    新动态类型的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. Using Compiled Python Classes from .NET/CSharp IP 2.6
    2. Static Compilation of IronPython scripts
        4
  •  -4
  •   Andrew Hare    15 年前

    我搜索了高低,恐怕没有太多与此相关的信息。我非常肯定,没有人设计出一种方法,以你希望的干净方式来做到这一点。

    我认为这是一个问题的主要原因是为了看到 PokerCard 输入您的C应用程序,您必须将您的python代码编译为il。我不相信有巨蟒 -> IL编译器就在那里。