C#調(diào)用Python腳本程序的兩種方法
為什么需要C#調(diào)用python?
有以下幾個(gè)原因需要C#調(diào)用Python:
Python擁有豐富的生態(tài)系統(tǒng):Python有很多強(qiáng)大的第三方庫(kù)和工具,可以用于數(shù)據(jù)科學(xué)、機(jī)器學(xué)習(xí)、自然語(yǔ)言處理等領(lǐng)域。通過C#調(diào)用Python,可以利用Python的生態(tài)系統(tǒng)來完成一些特定的任務(wù)。
C#和Python的優(yōu)勢(shì)互補(bǔ):C#是一種高性能、靜態(tài)類型的編程語(yǔ)言,適合用于開發(fā)大型應(yīng)用程序和高性能的系統(tǒng)。而Python則是一種動(dòng)態(tài)類型的腳本語(yǔ)言,適合用于快速開發(fā)原型和處理復(fù)雜的數(shù)據(jù)分析任務(wù)。通過C#調(diào)用Python,可以充分發(fā)揮兩者的優(yōu)勢(shì)。
C#和Python在不同領(lǐng)域的應(yīng)用:C#主要應(yīng)用于Windows平臺(tái)的開發(fā),而Python則可以用于各種平臺(tái),包括Windows、Linux和Mac OS。通過C#調(diào)用Python,可以在C#應(yīng)用程序中使用Python的功能和特性,實(shí)現(xiàn)更廣泛的應(yīng)用場(chǎng)景。
如何實(shí)現(xiàn)C#調(diào)用python腳本程序?
方式一:通過C#IronPython開源庫(kù)
IronPython是一個(gè)基于.NET平臺(tái)的Python解釋器。它是使用C#編寫的,可以被集成到.NET應(yīng)用程序中,并且可以直接調(diào)用和使用.NET庫(kù)和組件。IronPython提供了一個(gè)Python語(yǔ)言的實(shí)現(xiàn),同時(shí)具備了與.NET平臺(tái)無縫集成的能力。
IronPython最初由微軟開發(fā)并發(fā)布,旨在提供一個(gè)Python解釋器,使Python開發(fā)人員能夠利用.NET框架的優(yōu)勢(shì)。IronPython是完全兼容Python 2.7語(yǔ)法和語(yǔ)義的,并且還支持一些Python 3的一些特性。IronPython可以通過.NET編譯器將Python代碼轉(zhuǎn)換為托管代碼,并與.NET框架進(jìn)行交互。
IronPython具有以下特點(diǎn)和優(yōu)勢(shì):
- 與.NET框架的深度集成:IronPython可以直接與.NET庫(kù)和組件進(jìn)行交互,可以輕松使用和調(diào)用.NET的功能和類庫(kù)。
- 動(dòng)態(tài)語(yǔ)言的靈活性:作為一種動(dòng)態(tài)類型的腳本語(yǔ)言,IronPython具有動(dòng)態(tài)性和靈活性,可以進(jìn)行快速的原型開發(fā)和動(dòng)態(tài)腳本編寫。
- 跨平臺(tái)支持:IronPython可以在Windows、Linux和Mac OS等多個(gè)平臺(tái)上運(yùn)行,并且可以與不同平臺(tái)的.NET應(yīng)用程序集成。
- 社區(qū)支持和活躍度:IronPython擁有活躍的開源社區(qū),有大量的開發(fā)者和用戶為其貢獻(xiàn)代碼和提供支持。
總之,IronPython是一個(gè)具有.NET集成和跨平臺(tái)支持的Python解釋器,可以在.NET平臺(tái)開發(fā)中使用Python語(yǔ)言和功能。

缺點(diǎn):
1)只支持到python 3.4的相關(guān)特性, 和目前主流的python 3.9, 3.10,3.11等版本相差甚遠(yuǎn),會(huì)導(dǎo)致很多python流行的開源庫(kù)(比如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調(diào)用" 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="調(diào)用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="輸入?yún)?shù):" Grid.Row="1" Margin="5"/>
<TextBlock Text="輸出結(jié)果:" 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($"數(shù)組的和是:{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);
}
}
}
運(yùn)行效果

方式二: 通過Process類來運(yùn)行python解釋器
優(yōu)缺點(diǎn)
優(yōu)點(diǎn):可以使用python當(dāng)前的主流版本,并且可以使用大部分的流行的開源庫(kù)。
缺點(diǎn):只能通過命令行參數(shù)和控制臺(tái)輸出與python進(jìn)行通信。
安裝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($"數(shù)組的和是:{sum}");
}
/// <summary>
/// 調(diào)用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($"執(zhí)行python腳本開始------------");
p.Start();
/*string output = p.StandardOutput.ReadToEnd(); //讀取控制臺(tái)的輸出信息
p.WaitForExit(); // 等待外部程序進(jìn)行完畢
_WriteLog(output);
_WriteLog($"執(zhí)行python腳本結(jié)束------------ exit code: {p.ExitCode}");*/
// 如果使用異步讀取輸出流,python程序不會(huì)自動(dòng)退出,調(diào)用WaitForExit會(huì)阻塞,
// 必須自己根據(jù)返回來的字符串來決定程序是否已經(jīng)執(zhí)行完成
p.BeginOutputReadLine();
p.OutputDataReceived += new DataReceivedEventHandler(outputDataReceived);
}
/// <summary>
/// 輸出執(zhí)行python腳本的控制臺(tái)信息
/// </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($"執(zhí)行python腳本結(jié)束");
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);
});
}
}
}
運(yùn)行效果

到此這篇關(guān)于C#調(diào)用Python腳本程序的兩種方法的文章就介紹到這了,更多相關(guān)C#調(diào)用Python腳本內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#使用IronPython調(diào)用Python的實(shí)現(xiàn)
本文主要介紹了C#使用IronPython調(diào)用Python的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02
基于C#動(dòng)手實(shí)現(xiàn)網(wǎng)絡(luò)服務(wù)器Web Server
這篇文章主要為大家詳細(xì)介紹了基于C#動(dòng)手實(shí)現(xiàn)網(wǎng)絡(luò)服務(wù)器Web Server,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10
C#實(shí)現(xiàn)操作windows系統(tǒng)服務(wù)(service)的方法
這篇文章主要介紹了C#實(shí)現(xiàn)操作windows系統(tǒng)服務(wù)(service)的方法,可實(shí)現(xiàn)系統(tǒng)服務(wù)的啟動(dòng)和停止功能,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
使用GetInvalidFileNameCharts生成文件名
這篇文章主要介紹了一個(gè)很實(shí)用的函數(shù)Path.GetInvalidFileNameCharts(),他可以很方便的生成一個(gè)有效的文件名稱2014-01-01
C# lambda表達(dá)式應(yīng)用如何找出元素在list中的索引
這篇文章主要介紹了C# lambda表達(dá)式應(yīng)用如何找出元素在list中的索引的相關(guān)資料,需要的朋友可以參考下2018-01-01

