一 、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 numpyimport osimport sysdef Add(a,b): return a+bif __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