C#에서 파이썬 클래스 인스턴스화
-
06-09-2019 - |
문제
나는 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 클래스. 그들은 Python metaclass 인 ironpython.runtime.types.pythontype의 인스턴스입니다. 이는 파이썬 클래스가 동적이며 런타임에 메소드의 추가 및 제거, .NET 클래스에서는 할 수없는 일이 있기 때문입니다.
C#에서 Python 클래스를 사용하려면 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);
NUGET 지원과 함께 Visual Studio 2010 이상을 사용하는 경우 적절한 라이브러리를 다운로드하고 참조하기 위해이를 실행하십시오.
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이 .py 파일의 Ironpython 소스 코드 대신 Compiled Ironpython 클래스 (DLL)를 위해 제공 한 위의 예를 업데이트하고 있습니다.
# 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);
참조 :
나는 높고 낮은 검색을했으며 이것과 관련된 많은 정보가없는 것 같습니다. 나는 아무도 당신이 원하는 깨끗한 방식으로 이것을 할 수있는 방법을 고안하지 않았다고 확신합니다.
이것이 문제라고 생각하는 주된 이유는 PokerCard
C# 응용 프로그램을 입력하십시오. 파이썬 코드를 IL로 컴파일해야합니다. 나는 파이썬이 있다고 생각하지 않습니다->
IL 컴파일러가 있습니다.