C#调用Python脚本程序的两种方法

 更新时间:2024年02月19日 10:34:51   作者:老狼IT工作室  
本文主要介绍了C#调用Python脚本程序的两种方法,包含介绍了通过C#IronPython开源库和通过Process类来运行python解释器这两种,具有一定的参考价值,感兴趣的可以了解一下

为什么需要C#调用python?

有以下几个原因需要C#调用Python:

  • Python拥有丰富的生态系统:Python有很多强大的第三方库和工具,可以用于数据科学、机器学习、自然语言处理等领域。通过C#调用Python,可以利用Python的生态系统来完成一些特定的任务。

  • C#和Python的优势互补:C#是一种高性能、静态类型的编程语言,适合用于开发大型应用程序和高性能的系统。而Python则是一种动态类型的脚本语言,适合用于快速开发原型和处理复杂的数据分析任务。通过C#调用Python,可以充分发挥两者的优势。

  • C#和Python在不同领域的应用:C#主要应用于Windows平台的开发,而Python则可以用于各种平台,包括Windows、Linux和Mac OS。通过C#调用Python,可以在C#应用程序中使用Python的功能和特性,实现更广泛的应用场景。

如何实现C#调用python脚本程序?

方式一:通过C#IronPython开源库

IronPython是一个基于.NET平台的Python解释器。它是使用C#编写的,可以被集成到.NET应用程序中,并且可以直接调用和使用.NET库和组件。IronPython提供了一个Python语言的实现,同时具备了与.NET平台无缝集成的能力。

IronPython最初由微软开发并发布,旨在提供一个Python解释器,使Python开发人员能够利用.NET框架的优势。IronPython是完全兼容Python 2.7语法和语义的,并且还支持一些Python 3的一些特性。IronPython可以通过.NET编译器将Python代码转换为托管代码,并与.NET框架进行交互。

IronPython具有以下特点和优势:

  • 与.NET框架的深度集成:IronPython可以直接与.NET库和组件进行交互,可以轻松使用和调用.NET的功能和类库。
  • 动态语言的灵活性:作为一种动态类型的脚本语言,IronPython具有动态性和灵活性,可以进行快速的原型开发和动态脚本编写。
  • 跨平台支持:IronPython可以在Windows、Linux和Mac OS等多个平台上运行,并且可以与不同平台的.NET应用程序集成。
  • 社区支持和活跃度:IronPython拥有活跃的开源社区,有大量的开发者和用户为其贡献代码和提供支持。

总之,IronPython是一个具有.NET集成和跨平台支持的Python解释器,可以在.NET平台开发中使用Python语言和功能。

IronPython.net /

缺点:

1)只支持到python 3.4的相关特性, 和目前主流的python 3.9, 3.10,3.11等版本相差甚远,会导致很多python流行的开源库(比如scikit-learn),无法正常使用。

IronPython使用案例

NuGet安装IronPython

test.py

def sayHi():
    print("hello you")
    
def add(x,y):
    try:
        print(f"add {x}, {y}")
        return x + y
    except Exception as err:
        return str(err)
        
def sum(arr):
    try:
        print(f"sum {arr}")
        sum = 0
        for i in arr:
            sum += i
        return sum
    except Exception as err:
        return str(err)

PythonScriptWindow.axml

<Window x:Class="CallPythonDemos.PythonScriptWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:CallPythonDemos"
        mc:Ignorable="d"
        Title="Python Script调用" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Button x:Name="btnCallPythonScript" Content="调用python脚本" Grid.Row="0" Margin="5" Click="btnCallPythonScript_Click"/>
        <Button x:Name="btnClearOutput" Content="清理输出" Grid.Row="0" Grid.Column="1" Margin="5" Click="btnClearOutput_Click"/>
        <TextBlock Text="输入参数:" Grid.Row="1" Margin="5"/>
        <TextBlock Text="输出结果:" Grid.Row="1" Grid.Column="1" Margin="5"/>
        <TextBox x:Name="txtInputParam" Grid.Row="2" Margin="5"/>
        <RichTextBox x:Name="txtOutputResult" Grid.Row="2" Grid.Column="1" Margin="5" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto" IsReadOnly="True">
            <RichTextBox.Document>
                <FlowDocument/>
            </RichTextBox.Document>
        </RichTextBox>
    </Grid>
</Window>

PythonScriptWindow.axml.cs

using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
using System.Diagnostics;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;

namespace CallPythonDemos
{
    /// <summary>
    /// PythonScriptWindow.xaml 的交互逻辑
    /// </summary>
    public partial class PythonScriptWindow : Window
    {
        public PythonScriptWindow()
        {
            InitializeComponent();
        }

        private void btnCallPythonScript_Click(object sender, RoutedEventArgs e)
        {
            _RunTestByIronPython();
        }

        private void btnClearOutput_Click(object sender, RoutedEventArgs e)
        {
            txtOutputResult.Document.Blocks.Clear();
        }

        private void _RunTestByIronPython()
        {
            ScriptEngine pyEngine = Python.CreateEngine();
            dynamic testpy = pyEngine.ExecuteFile("test.py");
            testpy.sayHi();

            var add = testpy.add(3, 5);
            _WriteLog($"add 方法的和是:{add}");

            int[] arr = new int[3] { 2, 4, 6 };
            var sum = testpy.sum(arr);
            _WriteLog($"数组的和是:{sum}");
        }

        private void _WriteLog(string? log)
        {
            Paragraph para = new Paragraph() { Margin = new Thickness(0) };
            para.Inlines.Add(new Run(log) { Foreground = Brushes.Black });
            txtOutputResult.Document.Blocks.Add(para);
        }
    }
}

运行效果

方式二: 通过Process类来运行python解释器

优缺点

优点:可以使用python当前的主流版本,并且可以使用大部分的流行的开源库。

缺点:只能通过命令行参数和控制台输出与python进行通信。

安装scikit-learn

pip install scikit-learn

gen_model.py

from sklearn import linear_model
if __name__ == '__main__':
    reg = linear_model.LinearRegression()
    reg.fit([[0, 0], [1, 1], [2, 2]], [0, 1, 2])
    print('coef_:', reg.coef_)
    print('intercept_:', reg.intercept_)
    print('done')

PythonScriptWindow.axml.cs

using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
using System.Diagnostics;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;

namespace CallPythonDemos
{
    /// <summary>
    /// PythonScriptWindow.xaml 的交互逻辑
    /// </summary>
    public partial class PythonScriptWindow : Window
    {
        public PythonScriptWindow()
        {
            InitializeComponent();
        }

        private void btnCallPythonScript_Click(object sender, RoutedEventArgs e)
        {
            //_RunTestByIronPython();
            _RunPythonScript();
        }

        private void btnClearOutput_Click(object sender, RoutedEventArgs e)
        {
            txtOutputResult.Document.Blocks.Clear();
        }

        private void _RunTestByIronPython()
        {
            ScriptEngine pyEngine = Python.CreateEngine();
            dynamic testpy = pyEngine.ExecuteFile("test.py");
            testpy.sayHi();

            var add = testpy.add(3, 5);
            _WriteLog($"add 方法的和是:{add}");

            int[] arr = new int[3] { 2, 4, 6 };
            var sum = testpy.sum(arr);
            _WriteLog($"数组的和是:{sum}");
        }
        /// <summary>
        ///  调用python脚本
        /// </summary>

        private void _RunPythonScript()
        {
            Process p = new Process();
            p.StartInfo.FileName = "D:/my_project/Anaconda3/envs/jupyterlab_py310/python.exe";
            p.StartInfo.Arguments = "D:/my_project/first_board_debug/gen_model.py";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            _WriteLog($"执行python脚本开始------------");
            p.Start();
            /*string output = p.StandardOutput.ReadToEnd(); //读取控制台的输出信息
            p.WaitForExit();  // 等待外部程序进行完毕
            _WriteLog(output);
            _WriteLog($"执行python脚本结束------------ exit code: {p.ExitCode}");*/
            // 如果使用异步读取输出流,python程序不会自动退出,调用WaitForExit会阻塞,
            // 必须自己根据返回来的字符串来决定程序是否已经执行完成
            p.BeginOutputReadLine();
            p.OutputDataReceived += new DataReceivedEventHandler(outputDataReceived);
        }

        /// <summary>
        /// 输出执行python脚本的控制台信息
        /// </summary>
        private void outputDataReceived(object sender, DataReceivedEventArgs e)
        {
            if (!string.IsNullOrEmpty(e.Data))
            {
                _WriteLog(e.Data);
                if (e.Data == "done")
                {
                    var p = sender as Process;
                    if(p!=null)
                    {
                        _WriteLog($"执行python脚本结束");
                        p.Close();
                    }
                }
            }
        }

        private void _WriteLog(string? log)
        {
            this.Dispatcher.Invoke(() => {
                Paragraph para = new Paragraph() { Margin = new Thickness(0) };
                para.Inlines.Add(new Run(log) { Foreground = Brushes.Black });
                txtOutputResult.Document.Blocks.Add(para);
            });
        }
    }
}

运行效果

到此这篇关于C#调用Python脚本程序的两种方法的文章就介绍到这了,更多相关C#调用Python脚本内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C#控制图像旋转和翻转的方法

    C#控制图像旋转和翻转的方法

    这篇文章主要介绍了C#控制图像旋转和翻转的方法,涉及C#图像操作中RotateFlip方法的相关使用技巧,需要的朋友可以参考下
    2015-06-06
  • C#实现给PDF文档设置过期时间

    C#实现给PDF文档设置过期时间

    我们可以给一些重要文档或者临时文件设置过期时间和过期信息提示来提醒读者或管理者文档的时效性,并及时对文档进行调整、更新等。下面本文将介绍如何通过C#来给PDF文档设置过期时间的方法。需要的可以参考一下
    2022-01-01
  • C#中的高效IO库System.IO.Pipelines

    C#中的高效IO库System.IO.Pipelines

    这篇文章介绍了C#中的高效IO库System.IO.Pipelines,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • C#的XML两种代码注释实例说明

    C#的XML两种代码注释实例说明

    在C/C++,JAVA中,有两种注释,一种是单行注释,即两根反斜杠(//),另一种是多行注释,即以/*开头,以*/结尾,本文将详细介绍,需要的朋友可以参考下
    2012-12-12
  • C# List.Sort四种重载总结

    C# List.Sort四种重载总结

    本文详细分析了C#中List.Sort()方法的四种重载形式及其实现原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-12-12
  • C#监控文件夹变化的方法

    C#监控文件夹变化的方法

    这篇文章主要介绍了C#监控文件夹变化的方法,通过FileSystemWatcher类的方法来实现对文件夹的监控,是非常实用的技巧,需要的朋友可以参考下
    2014-11-11
  • C#程序最小化到托盘图标操作步骤与实现代码

    C#程序最小化到托盘图标操作步骤与实现代码

    设置窗体属性showinTask=false;加notifyicon控件notifyIcon1,为控件notifyIcon1的属性Icon添加一个icon图标;添加窗体最小化事件(首先需要添加事件引用)接下来介绍实现代码,感兴趣的朋友可以研究下
    2012-12-12
  • c# 应用NPOI获取Excel中的图片,保存至本地的算法

    c# 应用NPOI获取Excel中的图片,保存至本地的算法

    本文主要介绍了c# 应用NPOI获取Excel中的图片,保存至本地的算法。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • C#生成随机数的方法小结

    C#生成随机数的方法小结

    这篇文章主要介绍了C#生成随机数的方法,实例总结了C#生成随机数的相关技巧,非常具有实用价值,需要的朋友可以参考下
    2015-05-05

最新评论