C#調用python腳本——通過文件通信

C#調用python腳本

由於項目的上位機(採用C#編寫的winform程序)需要使用數據擬合等功能,而python作爲數據處理方面優秀的工具,衆多的第三方庫使得處理數據得心應手。於是考慮採用C#+Python混合編程的方式來實現上位機的相關功能。
通過查閱資料發現,C#調用python腳本主要有兩種方式:

  • 一是使用IronPython這個工具,但不巧的是目前只支持python2,IronPython3在GitHub上的公告顯示還在開發中,遂放棄(費了好大的勁,才搞明白)。

  • 另一種方式就是有C#程序使用Cmd命令行來調用Python腳本。在實際使用中發現無論是通過命令行由C#向python程序傳參,還是C#截取python的運行結果都存在數據轉換麻煩的困難。遂想通過統一的接口來實現,而操作系統中文件是相對統一的東西,於是考慮採用文件傳參的方式來實現功能。

實現思路如下:
類似於嵌入式中的通道通信,通過打開的文件進行數據交換。
在這裏插入圖片描述
C#程序部分:
將參數寫入文件的函數

private static bool saveToCSVFile(double[] x_value, double[] y_value)
{
	bool successwriteFlag = true;

	List<double> X = new List<double>(x_value);
    List<double> Y = new List<double>(y_value);

    StringBuilder strValue = new StringBuilder();
    StreamWriter fs = new StreamWriter(@"DataToPython.csv");

    try
    {
    	for (int i = 0; i < X.Count; i++)
    		{
    			strValue.Append(X[i].ToString());
                if (i < X.Count - 1)
                {
                	strValue.Append(",");
                }
                else
                {
                	strValue.Append("\n");
                }
             }
		for (int i = 0; i < Y.Count; i++)
        {
        	strValue.Append(Y[i].ToString());
            if (i < Y.Count - 1)
            {
            	strValue.Append(",");
            }
            else
            {
            	strValue.Append("\n");
            }
       	}
        fs.Write(strValue);
        }
        catch (Exception ex)
        {
       		successwriteFlag = false;
        }
        finally
        {
        	 fs.Dispose();
        }
        return successwriteFlag;
}

通過命令行啓動Python腳本的函數

private static bool runPythonCmd()
{
	bool successRunPythonFlag = true;
    var p = new Process();
    try
    {               
    	p.StartInfo.FileName = "cmd.exe";
        p.StartInfo.UseShellExecute = false;        //是否使用操作系統Shell啓動
        p.StartInfo.RedirectStandardInput = true;   //接受來自調用程序的接收信息
        p.StartInfo.RedirectStandardOutput = true;  //由調用程序獲取輸出信息
        p.StartInfo.RedirectStandardError = true;   //重定向標準錯誤輸出
        p.StartInfo.CreateNoWindow = true;          //不顯示cmd命令行窗口
        p.Start();

        p.StandardInput.WriteLine("python curvefitting.py"); //啓動python腳本
        p.StandardInput.WriteLine("exit");
        p.StandardInput.AutoFlush = true;
        p.WaitForExit();        //等待程序執行完退出進程                
     }
     catch(Exception ex)
     {
     	successRunPythonFlag = false;
     }
     finally
     {
     	p.Close();
     }
     return successRunPythonFlag;
}

Python程序部分:

import numpy as np
import csv

# 讀取csv文件
csv_data = csv.reader(open('DataToPython.csv', encoding='utf-8'))

x = []
y = []

# 按行分爲x,y數據
for i, row in enumerate(csv_data):
    if i == 0:
        x = list(map(int, row))
    if i == 1:
        y = list(map(int, row))

x = np.array(x)
y = np.array(y)

f = np.polyfit(x, y, 3)  # 擬合函數
fittingvalues = np.polyval(f, x)  # 擬合值
print(f)
p = np.poly1d(f)
print(p)
print(fittingvalues)

np.savetxt("Result.csv", f.reshape(1, -1), delimiter=',')

在C#主函數中調用代碼即可:

static void Main(string[] args)
{
	double[] x = { 1, 2, 3, 6, 8 };
    double[] y = { 10, 11, 13, 19, 20 };

    bool successwriteFlag = saveToCSVFile(x, y);
            
    if(successwriteFlag)
    {
    	bool successRunPythonFlag = runPythonCmd();
        if(successRunPythonFlag)
        {
        	Console.WriteLine("運行python腳本成功");
        }
		else
     	{
            Console.WriteLine("運行python腳本失敗");
        }
    }
    else
    {
    	Console.WriteLine("寫入csv文件失敗");
    }
}

END

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章