Python是AI领域的最主流的编程语言,没有之一。而应用开发领域则通常不会选用Python语言。如果遇到应用开发过程中涉及AI算法,那就必然要面对跨语言通讯的问题。今天来介绍下C#中执行Python脚本的方式之一,当然还有其他方式也能实现。
需要安装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偶尔库,或者一些路径会有异常,导致直接运行失败)
准备一个简单的Winform程序和Python脚本。Winform程序如下:
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.Threading.Tasks;
using System.Windows.Forms;
namespace CsharpCallPython
{
public partial class Form1 : Form
{
private Process progressTest;
public Form1()
{
InitializeComponent();
}
private void btnAdd_Click(object sender, EventArgs e)
{
try
{
//string path = Application.StartupPath + @"\CsharpCallPython.py";//py文件路径";
string path= "F:\\study\\mycode\\python\\PythonTest\\flaskdemo\\mypthondemo.py";
int a = Convert.ToInt32(txtA.Text);
int b = Convert.ToInt32(txtB.Text);
StartTest(path, a, b);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public void outputDataReceived(object sender, DataReceivedEventArgs e)
{
if (!string.IsNullOrEmpty(e.Data))
{
this.Invoke(new Action(() => {
this.txtResult.Text = e.Data;
}));
}
}
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 = @"D:\Python36\python.exe";//环境路径需要配置好Python的实际安装路径
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;
}
}
}
Python脚本如下:
# -*- coding: utf-8 -*-
"""
File Name: PythonTest
Author: Michael
date: 2022/10/27
"""
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)
从以上代码不难看出,这是个实现简单的加法运算的功能。为了严重在C#执行Python脚本的可行性,才写了个Python脚本来实现两个数的求和运算。
运行Winform程序,很快得出结果了:
【结论】:
通过这种方式,是可以实现Python脚本的最终运行。但这并不是跨语言通信的一般处理方式。因此还是有必要好好研究下RPC框架了。