一 、C#調用Python的使用總結


  由於項目的需要,需要通過C#調用Python文件(算法)。之前接觸不多,在測試試驗的過程遇到了挺多坑的,在這里將試驗的過程和結果在這里總結一下。

一.使用IronPython作為移植的依賴庫,直接調用python文件的函數接口。

  百度詞條:IronPython 是一種在 NET 和 Mono 上實現的 Python 語言,由 Jim Hugunin(同時也是 Jython 創造者)所創造。它的誕生是為了將更多的動態語音移植到NET Framework上。

  通過簡單的C#代碼實現對python文件內部函數的調用。這種方法可以說是最簡單直接的,但是,問題來了。IronPython的發布截止到2011年3月,就是說后面就沒有進行開發和更新了。Python的設計應用日新月異,相關的庫的設計和開發層出不窮。不能支持很多第三方庫的引用和加載是這種方法最大的缺陷,簡單的代碼我們也沒必要專門寫成python文件去給C#調用,C#自己都可以寫。

  這種方法建議大伙就別嘗試了,浪費時間。

       PS:(更正,IronPython還是有繼續更新發布的,最新版本是 2.7.10,發布於April 27, 2020。可以到網頁進行了解https://ironpython.net/,謝謝三樓糾正)

 

二.使用c++程序調用python文件,然后將其做成動態鏈接庫(dll),在c#中調用此dll文件。

  這種方法是最開始使用的,但由於運行速度太慢,所以排除使用,所以后續才有第三種方法。詳細如何操作,這里沒研究過就不介紹了(別人開發接口的dll,直接使用沒去了解具體操作)。

 

三.需要安裝python安裝包和庫環境,利用c#命令行,調用.py文件執行(最終使用方法)

  這種方法:通過C#命令行調用.py文件 == 通過python.exe 打開.py文件

  他的適用性強,你只要保證你的.py程序能夠通過python.exe打開,使用就不會有大問題,同時還有一些需要注意的點。

  (1)文件路徑不能使用相對路徑(例:path = ./文件名 或者path = 文件名 ),會報錯,這一塊我不清楚是否別人沒遇到,反正我的話是一直會報這種錯誤。

  解決方法也很簡單,要么用絕對路徑,要么導入os庫,通過os.path.dirname(__file__)可以得到當前文件的路徑,即path = os.path.dirname(__file__) + '\文件名'

  (2)路徑間隔需要用/代替\;同時“\\”作為輸入參數偶爾也會有出現異常的情況,原因不明。個人建議將輸入路徑參數全部提前替換

  (3)不能調用py文件的接口,函數方法

  (4)最好在程序前附加異常檢測處理(try,exception),便於獲取異常(C#調用Python偶爾庫,或者一些路徑會有異常,導致直接運行失敗)

if __name__=='__main__':
    try:
        #代碼行
        a = 1
    except Exception as err:
        #捕捉異常
        str1 = 'default:' + str(err)
    else:
        # 代碼運行正常
        str1 = "Code are operating normally."
    print(str1)

 

  測試步驟如下:

  1、下載安裝python,安裝環境庫

  我是通過Notepad++進行python程序編寫,安裝庫直接使用python自帶pip進行安裝。通過CMD直接進行安裝

  (1)下面介紹幾個常用的pip操作和如何安裝庫

    顯示pip的安裝列表:pip list
    安裝庫:pip install 庫名
    安裝對應版本的庫:pip install --upgrade 庫名==版本號
    卸載庫:pip uninstall 庫名

  (2)等待安裝完畢即可

  (3)注意網速問題,如果網速不好建議直接下載對應庫的離線安裝包(注意)

 

  2、通過VS編寫一個簡單的window窗口進行測試,C#界面和代碼如下

  有一些需要注意的地方,首先:文件路徑不能存在空格;輸入參數是路徑的建議全部替換'\\'為'/';

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ToolApp
{
    public partial class Example : Form
    {
        private Process progressTest;

        public Example()
        {
            InitializeComponent();
        }

        private void buttonAdd_Click(object sender, EventArgs e)
        {
            try
            {
                string path = Application.StartupPath + @"\Add.py";//py文件路徑
                int a = Convert.ToInt32(this.textBox1.Text);
                int b = Convert.ToInt32(this.textBox2.Text);
                StartTest(path, a, b);
            }
            catch(Exception e1)
            {
                MessageBox.Show(e1.Message);
            }
        }
        /// <summary>
        /// 開始測試
        /// </summary>
        /// <param name="pathAlg">py文件路徑</param>
        /// <param name="a">加數a</param>
        /// <param name="b">加數b</param>
        /// <returns></returns>
        public bool StartTest(string pathAlg, int a, int b)
        {
            bool state = true;

            if (!File.Exists(pathAlg))
            {
                throw new Exception("The file was not found.");
                return false;
            }
            string sArguments = pathAlg;
            sArguments += " " + a.ToString() + " " + b.ToString() + " -u";//Python文件的路徑用“/”划分比較常見

            ProcessStartInfo start = new ProcessStartInfo();
            start.FileName = @"python.exe";//環境路徑需要配置好
            start.Arguments = sArguments;
            start.UseShellExecute = false;
            start.RedirectStandardOutput = true;
            start.RedirectStandardInput = true;
            start.RedirectStandardError = true;
            start.CreateNoWindow = true;

            using (progressTest = Process.Start(start))
            {
                // 異步獲取命令行內容
                progressTest.BeginOutputReadLine();
                // 為異步獲取訂閱事件
                progressTest.OutputDataReceived += new DataReceivedEventHandler(outputDataReceived);
            }
            return state;
        }

        public void outputDataReceived(object sender, DataReceivedEventArgs e)
        {
            if (!string.IsNullOrEmpty(e.Data))
            {
                this.Invoke(new Action(() => {
                    this.textBox3.Text = e.Data;
                }));
            }
        }
    }
}

 

  3、通過Notepad++編寫一個簡單的加法函數,調用Python文件代碼如下,導入欄導入一些比較第三方的庫(為了測試看看第三方庫的導入是否正常)

import numpy
import os
import sys

def Add(a,b):
    return a+b

if __name__=='__main__':
    try:
        #代碼行
        a = int(sys.argv[1])
        b = int(sys.argv[2])
        c = Add(a,b)
    except Exception as err:
        #捕捉異常
        str1 = 'default:' + str(err)
    else:
        # 代碼運行正常
        str1 = c
    print(str1)

 

  4、生成成功,通過界面輸入兩組數字,點擊測試,可以成功得到結果,效果如下

  

 

 

 

———————————————————————————————————————————

如何使用IronPython,參考鏈接:https://www.cnblogs.com/ligiggy/p/11471071.html

四種方法調用,參考鏈接:https://blog.csdn.net/qq_42063091/article/details/82418630


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM