簡體   English   中英

在C#中實例化python類

[英]Instantiating a python class in C#

我在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函數會更容易。

我正在更新Clever Human為編譯的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. 使用.NET / CSharp IP 2.6中的編譯Python類
  2. IronPython腳本的靜態編譯

我已經搜索過高低,我擔心似乎沒有太多關於此的信息。 我很確定沒有人設計出一種方法,以你想要的干凈方式做到這一點。

我認為這是一個問題的主要原因是,為了在你的C#應用​​程序中看到PokerCard類型,你必須將你的Python代碼編譯成IL。 我不相信有任何Python -> IL編譯器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM