前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >c#调用python的四种方法(尝试了四种,只详细讲解本人成功的后两种,其余方法只列出,详细用法请自行谷歌百度)[通俗易懂]

c#调用python的四种方法(尝试了四种,只详细讲解本人成功的后两种,其余方法只列出,详细用法请自行谷歌百度)[通俗易懂]

作者头像
全栈程序员站长
发布2022-07-23 13:20:44
9.5K0
发布2022-07-23 13:20:44
举报
文章被收录于专栏:全栈程序员必看

大家好,又见面了,我是你们的朋友全栈君。

一、使用c#,nuget管理包上下载的ironPython安装包

尝试后发现,对引用了numpy等第三方库的python代码,会报找不到模块xxx的错误,上网查证后发现此问题基本难以解决

二、使用c++程序调用python文件,然后将其做成动态链接库(dll),在c#中调用此dll文件 限制:实现方式很复杂,并且受python版本、(python/vs)32/64位影响,而且要求用户必须安装python运行环境

三、使用安装好的python环境,利用c#命令行,调用.py文件执行

优点:执行速度只比在python本身环境中慢一点,步骤也相对简单

缺点:需要用户安装配置python环境

实用步骤:

1、下载安装python,并配置好环境变量等(本人用的Anaconda,链接此处不再提供)

2、编写python文件(这里为了便于理解,只传比较简单的两个参数)

注:这两个python文件,我引用了numpy第三方库,也要安装后才能在python中使用

代码语言:javascript
复制
#multi.py

def multiplication(a,b):
	return a*b
代码语言:javascript
复制
#main.py
import numpy as np
import multi
import sys

def func(a,b):
    result=np.sqrt(multi.multiplication(int(a),int(b)))
    return result


if __name__ == '__main__':
    print(func(sys.argv[1],sys.argv[2]))

ps:为了import不报错,尽量把multi.py文件放main.py同一文件夹下。因为打包exe文件执行后,可能会报找不到Multi模块的错误

3、在c#中调用上述主python文件:main.py

(我直接建了一个wpf文件,放在一个按钮的点击事件中执行了,你们随意)

代码语言:javascript
复制
        private void Button_Click(object sender, RoutedEventArgs e)
        {

            string[] strArr=new string[2];//参数列表
            string sArguments = @"main.py";//这里是python的文件名字
            strArr[0] = "2";
            strArr[1] = "3";
            RunPythonScript(sArguments, "-u", strArr);
        }
        //调用python核心代码
        public static void RunPythonScript(string sArgName, string args = "", params string[] teps)
        {
            Process p = new Process();
            string path = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase + sArgName;// 获得python文件的绝对路径(将文件放在c#的debug文件夹中可以这样操作)
            path = @"C:\Users\user\Desktop\test\"+sArgName;//(因为我没放debug下,所以直接写的绝对路径,替换掉上面的路径了)
            p.StartInfo.FileName = @"D:\Python\envs\python3\python.exe";//没有配环境变量的话,可以像我这样写python.exe的绝对路径。如果配了,直接写"python.exe"即可
            string sArguments = path;
            foreach (string sigstr in teps)
            {
                sArguments += " " + sigstr;//传递参数
            }

                sArguments += " " + args;

            p.StartInfo.Arguments = sArguments;

            p.StartInfo.UseShellExecute = false;

            p.StartInfo.RedirectStandardOutput = true;

            p.StartInfo.RedirectStandardInput = true;

            p.StartInfo.RedirectStandardError = true;

            p.StartInfo.CreateNoWindow = true;

            p.Start();
            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 delegate void AppendTextCallback(string text);
        public static void AppendText(string text)
        {
            Console.WriteLine(text);     //此处在控制台输出.py文件print的结果

        }

执行成功,得到结果:也就是

c#调用python的四种方法(尝试了四种,只详细讲解本人成功的后两种,其余方法只列出,详细用法请自行谷歌百度)[通俗易懂]
c#调用python的四种方法(尝试了四种,只详细讲解本人成功的后两种,其余方法只列出,详细用法请自行谷歌百度)[通俗易懂]

四、c#调用python可执行exe文件,使用命令行进行传参取返回值

优点:无需安装python运行环境

缺点:

1、可能是因为要展开exe中包含的python环境,执行速度相当慢,慎用!

2、因为是命令行传参形式,故传参需要自行处理。ps:由于命令行传参形式为:xxx.exe 参数1 参数2 参数3….

我要传一个很大的数组,曲线救国,用c#将数组写入txt文件中,将存放路径传给python函数,python读取此txt文件得到数据


使用步骤:

1、编写python文件(这里为了便于理解,只传比较简单的两个参数)

代码语言:javascript
复制
#multi.py

def multiplication(a,b):
	return a*b
代码语言:javascript
复制
#main.py
import numpy as np
import multi
import sys

def func(a,b):
    result=np.sqrt(multi.multiplication(int(a),int(b)))
    return result


if __name__ == '__main__':
    print(func(sys.argv[1],sys.argv[2]))

ps:为了import不报错,尽量把multi.py文件放main.py同一文件夹下。因为打包exe文件执行后,可能会报找不到Multi模块的错误

2、安装pyInstaller(若已安装请直接跳过此步骤)

我使用的是Anaconda编写python,所以使用Anaconda Prompt进行安装pyInstaller(直接安装python并配好环境变量的小伙伴,可以在电脑的cmd下进行操作)

c#调用python的四种方法(尝试了四种,只详细讲解本人成功的后两种,其余方法只列出,详细用法请自行谷歌百度)[通俗易懂]
c#调用python的四种方法(尝试了四种,只详细讲解本人成功的后两种,其余方法只列出,详细用法请自行谷歌百度)[通俗易懂]

这个类似于电脑的cmd.exe程序,可在其中输入命令行操作

安装pyInstaller命令行:

c#调用python的四种方法(尝试了四种,只详细讲解本人成功的后两种,其余方法只列出,详细用法请自行谷歌百度)[通俗易懂]
c#调用python的四种方法(尝试了四种,只详细讲解本人成功的后两种,其余方法只列出,详细用法请自行谷歌百度)[通俗易懂]

正常来讲会报一个错误,说你的pip版本过低,需要先更新一下

代码语言:javascript
复制
pip install --upgrade pip

使用此命令更新pip,然后再执行pip install pyinstaller命令即可

3、使用pyinstaller打包python程序

同样还是在Anaconda Prompt中,cd python文件所在的路径,然后执行打包命令

c#调用python的四种方法(尝试了四种,只详细讲解本人成功的后两种,其余方法只列出,详细用法请自行谷歌百度)[通俗易懂]
c#调用python的四种方法(尝试了四种,只详细讲解本人成功的后两种,其余方法只列出,详细用法请自行谷歌百度)[通俗易懂]

打包过程可能会出错(找不到模块、迭代深度超出等,在我另两篇博客里有解决办法)

若打包成功,出现successfully,失败的话会给出错误信息

c#调用python的四种方法(尝试了四种,只详细讲解本人成功的后两种,其余方法只列出,详细用法请自行谷歌百度)[通俗易懂]
c#调用python的四种方法(尝试了四种,只详细讲解本人成功的后两种,其余方法只列出,详细用法请自行谷歌百度)[通俗易懂]

4、在c#中调用此exe文件(此处我建了一个wpf项目,利用按钮点击事件来实现调用)

代码语言:javascript
复制
namespace WpfTest2
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //string debugPath = System.Environment.CurrentDirectory;           //此c#项目的debug文件夹路径
            string pyexePath = @"C:\Users\user\Desktop\test\dist\main.exe";     
            //python文件所在路径,一般不使用绝对路径,此处仅作为例子,建议转移到debug文件夹下
            
            Process p = new Process();
            p.StartInfo.FileName = pyexePath;//需要执行的文件路径
            p.StartInfo.UseShellExecute = false; //必需
            p.StartInfo.RedirectStandardOutput = true;//输出参数设定
            p.StartInfo.RedirectStandardInput = true;//传入参数设定
            p.StartInfo.CreateNoWindow = true;
            p.StartInfo.Arguments = "2 3";//参数以空格分隔,如果某个参数为空,可以传入””
            p.Start();
            string output = p.StandardOutput.ReadToEnd();
            p.WaitForExit();//关键,等待外部程序退出后才能往下执行}
            Console.Write(output);//输出
            p.Close();        
        }
    }
}

在控制台打印出结果:也就是

c#调用python的四种方法(尝试了四种,只详细讲解本人成功的后两种,其余方法只列出,详细用法请自行谷歌百度)[通俗易懂]
c#调用python的四种方法(尝试了四种,只详细讲解本人成功的后两种,其余方法只列出,详细用法请自行谷歌百度)[通俗易懂]

至此,完成c#调用python的exe文件,并实现了传入传出参数功能,谢谢观看

第三种实现方式整理了下源代码,下载链接放在下面,需要的话请自行下载:

百度网盘免费链接和提取码:

链接:https://pan.baidu.com/s/1YBcjdr-0fo0HVP1sq1U7nw 提取码:zana

CSDN收费链接:netCallpyFile.rar_c#调用python-C#文档类资源-CSDN下载

里面有注意事项,代码运行出现问题时最好看一下。有其他问题可以在下面评论或者私信我,可能回复不及时,请谅解,谢谢支持

2019-5-16更新,补充一点,path中不能带有空格,尽量不要有中文。不然会出现不报错,但执行也不出结果的情况,

因为此种方式本质上类似与管理员命令行中执行:python.exe c:\hua bei\main.py 2 3 的效果。如黄色字体中的空格,会导致执行变成 python.exe c:\hua …,也就是把c:\hua 当成.py文件的路径,所以导致执行不出结果,希望大家避免踩坑

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/126331.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年4月7,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档