본문 바로가기
C#, MONO

c#과 Python의 연동

by gigasound 2021. 8. 11.


C#과 Python 연결

Linux에서 Python의 입지는 매우 큽니다. 특히 머신 러닝(machine learing) 관련된 내용은 Python으로 작성된 결과가 많아, 이를 c#에서 직접 사용하고 싶은 욕망이 큽니다.

이 글에서는 Python의 코드 내용을 실행하고 결과를 얻는 방법을 알아보겠습니다.

 


C#에서 Python 설치

먼저 VisualStuio에서 c# 프로젝트를 만들고 Nuget 패키지 관리로 IronPython을 참조로 추가합니다. 

그러면 c#에서 python으로 접근할 수 있게 됩니다.


Python class의 함수로 접근

먼저 python에서 Calculator.py의 class를 만들고 덧셈을 실행하는 함수를 선언합니다.

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

c# 코드를 다음과 같이 선언하고 Calculator.py에 접근합니다. 

그리고 python 함수를 실행해서 결과를 얻을 수 있습니다.

using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
using IronPython;
using IronPython.Hosting;
using IronPython.Runtime;
using IronPython.Modules;

//- 실행 코드 내부에 선언 
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);

python 함수에서 각종 데이터 얻기

함수로 정의돼 부분에서 결과를 반환받거나, 리스트로 반환받을수도 있습니다. 먼저 simple.py를 생성합니다.

def test1():
    data = 'test1'
    return data 
 
def test2( data ):
    return data 

def ListTest():
    data = []
    data.append('test1')
    data.append('test2')
    data.append('1234566') 
    return data

class MyClass(object):
    def __init__(self, value):
        self.value = "1234"
    def add(self,x,y) :
        return x + y

c# 코드는 다음과 같이 만듭니다.

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
using IronPython;
using IronPython.Hosting;
using IronPython.Runtime;
using IronPython.Modules;
using System.Xml.XPath;

namespace test2 {
	public class MyPython{
		private ScriptEngine engine;
		private ScriptScope scope;
		private ScriptSource source;
		private const string pythonFile = "simple.py";
		//private ObjectOperations op;
		public bool valid = false;
        
		/// <summary>
		/// Python에 접근하는 객체 생성자 
		/// </summary>
		public MyPython(){
			FileInfo fileInfo = new FileInfo(pythonFile);
			if(fileInfo.Exists==false){
				this.valid = false;
				return;
			}
			this.valid = true;
			this.engine = IronPython.Hosting.Python.CreateEngine();
			this.scope = this.engine.CreateScope();
			//this.op = engine.Operations;
			try {
				//- 접근 함수 선언
				this.source = engine.CreateScriptSourceFromFile("simple.py");
                //- 함수 실행 
				this.source.Execute(scope);
			}
			catch(Exception ex){
				Console.WriteLine(ex.Message);
			}
		}
        
        /// <summary>
        /// 함수에 접근 
        /// </summary>
		public string test1(){
			string ret;
			try{
            	//- 접근 함수 선언
				var func = scope.GetVariable<Func<object>>("test1");
                //- 함수 실행 
				ret = func().ToString();
			}
			catch(Exception){return "";}
			return ret;
		}
        
		/// <summary>
		/// 한개의 입력 인자 
		/// </summary>
		public string test2(){
			string ret;
			try{
            	//- 접근 함수 선언
				var func = this.scope.GetVariable<Func<object,object>>("HelloWorld2");
                //- 점근 함수에 인자 입력해서 실행 
                ret = func("haha").ToString();
			}
			catch(Exception) {return "";}
			return ret;
		} 
		/// <summary>
		/// ListTest, 리스트 출력 
		/// </summary>
		public IronPython.Runtime.List getList(){
        	//- python용 리스트 선언
			IronPython.Runtime.List r = new IronPython.Runtime.List();
			try {
            	//- 함수 선언
				var func = scope.GetVariable<Func<object>>("ListTest");
				//- 함수 실행
                r = (IronPython.Runtime.List)func();
			}	
			catch(Exception){
				r.Clear();
				return r;
			}
			return r;
		}
		
        /// <summary>
		/// 클래스에 접근 
		/// </summary>
		public string getClassMember(){
			string ret;
			var myClass = scope.GetVariable<Func<object,object>>("MyClass");
			var myInstance = myClass("hello");
			ret = engine.Operations.GetMember(myInstance,"value");
			return ret;
		}
	} //- clasee
} //- name space

코드의 내용은 단순합니다. 그러나 오류가 발생할 때를 고려해서 안정 장치를 포함해야만 합니다. 

 

 


광고좀 꾹 눌러주시면 고맙겠습니다. 


참조 :

https://stackoverflow.com/questions/579272/instantiating-a-python-class-in-c-sharp
https://vmpo.tistory.com/55
https://siran.tistory.com/46
https://stackoverrun.com/ko/q/88529
https://kdsoft-zeros.tistory.com/category/C%23%20Programming

위의 내용을 참조용으로만 사용해주세요. 무단 도용이나 무단 복제는 불허합니다.

기타 문의 사항은 gigasound@naver.com에 남겨 주시면 고맙겠습니다.

'C#, MONO' 카테고리의 다른 글

로그(Log) 를 남기고, 오래된 로그 파일 자동 삭제  (0) 2021.08.14
c#에서 ssh scp로 bash 명령어 실행 및 파일 전송  (0) 2021.08.11
Enum의 정보 변환 하기  (0) 2021.08.11
문장 변환 정리(1)  (0) 2021.08.11
SQlite  (0) 2021.08.10