C#调用Python文件

今天试用了好几种方法,最终只有一个方法成功,现将今天的收获和问题做个笔记

方法一:使用ironPython

这个方法首先要在VS中安装配置ironPython,且如果python脚本中包含第三方模块,这个方法大多会报错说找不到import的包(但有的也能成功),在网上也很难找到该问题的解决方法,所以这个方法比较使用于调用不包含第三方模块的python脚本。
C#代码

using Microsoft.Scripting.Hosting;
using IronPython.Hosting;
	//在具体方法里面写如下代码
	ScriptEngine pyEngine = Python.CreateEngine();//创建Python解释器对象
	dynamic py = pyEngine.ExecuteFile("new.py");//读取脚本文件
	double str =123.789;
	py.test(str);//调用new.py文件中的test方法,并传入参数

方法二:使用ScriptRuntime

这个方法不需要另外安装东西,我一个同学是使用这个方法成功了,可以调用包含第三方模块的Python脚本,但是我的不行,可能是各自的环境不同。
C#代码

using Microsoft.Scripting.Hosting;
	//在具体方法里面写如下代码
	ScriptRuntime scriptRuntime = ScriptRuntime.CreateFromConfiguration();
	ScriptEngine rbEng = scriptRuntime.GetEngine("Python");
	dynamic py = scriptRuntime.UseFile("Models.py");//将Python脚本“Models.py”放在C#项目的Debug文件下,若不是就写文件的绝对路径
	py.main(modelName, inputPath, resultKind, resultPath);//调用python脚本的main()方法,并传入参数

方法三:使用Process

这个方法也不需要另外安装东西,不管调用的Python脚本是否包含第三方模块都比较适用,而且我也试验成功了,就是代码多了一点,不过这个方法大多数都普遍适用。
C#代码

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Scripting.Hosting;
using System.Collections;
	public void Use_model(string modelName, string txtpathTrainTest,string txtpathApply, string resultKind, string resultPath)
	{
		Process p = new Process();
		string path = "Models.py";//待处理python文件的路径,本例中放在debug文件夹下
	    string sArguments = path;  
	    /* 如果Python脚本中不需传入参数,这段可省略         
	    ArrayList arrayList = new ArrayList();
	    arrayList.Add(modelName);//modelName是参数变量
	    arrayList.Add(txtpathTrainTest);
	    arrayList.Add(txtpathApply);
	    arrayList.Add(resultKind);
	    arrayList.Add(resultPath);
	    foreach (var param in arrayList)//添加参数
	    {
	        sArguments += " " + param;
	    }
	    */
	    p.StartInfo.FileName = @"D:\software\Python\Result\Python 2.7\python.exe"; //python2.7的安装路径,若配置了python的环境变量,可以直接写成"python.exe"
	    p.StartInfo.Arguments = sArguments;//python命令的参数,若不传参,则只有Python脚本的路径
	    p.StartInfo.UseShellExecute = false;
	    p.StartInfo.RedirectStandardOutput = true;
	    p.StartInfo.RedirectStandardInput = true;
	    p.StartInfo.RedirectStandardError = true;
	    p.StartInfo.CreateNoWindow = true;
	    p.Start();//启动进程 
    }

Python代码

import sys  #导入sys module
def setupTxt(modelName, txtpathTrainTest, txtpathApply, resultKind, resultPath):
	x_train,x_test,y_train,y_test,predict_x=get_txtdata(txtpathTrainTest,txtpathApply)	
	anwser_all,probas_all,probas_test=analysis_data(modelName,x_train,x_test,y_train,y_test,predict_x)
	output_data(y_test,anwser_all,probas_all,probas_test,resultKind,resultPath)
#主要是下面这一行代码,sys.argv[i]就是C#那边传过来的参数,直接调用上面是自定义的方法setupTxt
setupTxt(sys.argv[1], sys.argv[2], sys.argv[3],sys.argv[4],sys.argv[5])

**注:**如果是窗体应用,又想要查看Python脚本中的参数值,可以直接在python中写print()方法,然后在VS中进行如下设置:
1、[项目名称]——>右键[属性]——>[应用程序]——>修改[输出类型]为“控制台应用程序”
2、若使用的是方法三,则在以上代码后面还需添加如下代码:

	p.BeginOutputReadLine();
	p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
	Console.ReadLine();
	p.WaitForExit();//以上部分写在上面方法三的函数代码后面
	//下面另外定义函数方法,以输出打印的信息
    static void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        if (!string.IsNullOrEmpty(e.Data))
        {
            AppendText(e.Data + Environment.NewLine);
        }
    }
    public static void AppendText(string text)
    {
        Console.WriteLine(text);     //此处在控制台输出.py文件print的结果

    }

借鉴博客及文章:https://blog.csdn.net/qq_42063091/article/details/82418630
http://www.cnblogs.com/zoe-yan/p/10374757.html

你可能感兴趣的:(C#,C#,Python)