目录
Pythonnet Package & 开始
示例 1 – 使用Pythonnet的Hello World
示例 2 – Pythonnet计算器!
示例 3 – 对象互操作
总结
Python和C#是两种非常流行的语言。作为一名主要是C#开发人员,我发现在某些情况下我想与Python交互。下面是使用“Python for .NET”包作为从C#代码调用Python的一种方式的示例。
Python是一种功能强大且通用的编程语言,已变得越来越流行。对于许多人来说,这是他们在入门时最早选择的编程语言之一。我博客上一些流量最高的帖子是在写完很多年后写的,都是关于同时使用C#和Python的。今天,我们将探讨如何从C# .NET Core应用程序内部使用Python,其方法比我的原始文章要现代得多。进入Pythonnet!
我们将研究Python的.NET来实现这一目标。此库允许您从.NET Core应用程序中利用安装在正在运行的计算机上的Python。您必须将其配置为指向要使用的相应Python DLL,并且在几行初始化之后,您就可以开始比赛了!
若要开始,需要从NuGet安装 pythonnet 包。完成此操作后,可以使用以下代码从C#代码运行Python脚本:
using Python.Runtime;
internal sealed class Program
{
private static void Main(string[] args)
{
// NOTE: set this based on your python install. this will resolve from
// your PATH environment variable as well.
Runtime.PythonDLL = "python310.dll";
PythonEngine.Initialize();
using (Py.GIL())
{
using var scope = Py.CreateScope();
scope.Exec("print('Hello World from Python!')");
}
}
}
这段代码在运行时上设置我们的python DLL路径,这将是一个必要的步骤。不要忘记这样做!然后我们必须调用PythonEngine.Initialize()和Py.GIL(),我们稍后会想要处理它,因此请考虑一个using声明。我们可以要求static Py类创建一个作用域供我们使用,然后利用 Exec方法来执行一些Python代码。在此示例中,我们调用 Exec方法来运行一个简单的Python脚本,该脚本将“Hello World from Python!”打印到控制台。
还可以使用Python C API直接从C#代码调用Python函数。为此,需要为要调用的Python函数创建C#包装器。下面是一个示例,说明如何为Python函数创建包装器,该函数将两个整数作为参数并返回其总和:
using System;
using Python.Runtime;
internal sealed class Program
{
private static void Main(string[] args)
{
// NOTE: set this based on your python install. this will resolve from
// your PATH environment variable as well.
Runtime.PythonDLL = "python310.dll";
PythonEngine.Initialize();
using (Py.GIL())
{
// NOTE: this doesn't validate input
Console.WriteLine("Enter first integer:");
var firstInt = int.Parse(Console.ReadLine());
Console.WriteLine("Enter second integer:");
var secondInt = int.Parse(Console.ReadLine());
using dynamic scope = Py.CreateScope();
scope.Exec("def add(a, b): return a + b");
var sum = scope.add(firstInt, secondInt);
Console.WriteLine($"Sum: {sum}");
}
}
}
在此示例中,我们使用 Exec方法定义一个名为add的Python函数,该函数将两个整数作为参数并返回它们的sum。多亏了C#中的dynamic关键字,我们能够假设我们的scope对象有一个直接调用的add方法。最后,我们直接使用C#代码来调用该add方法,就像在C#中一样。在C#中分配给sum变量的返回类型也是动态的,但您可以将此变量声明为整数,它也可以使用此类型正确编译。
控制台窗口中的结果来自我们简单的Pythonnet计算器!
我们还可以将Python对象传递给C#函数,反之亦然。下面是一个示例,说明如何在不使用dynamic关键字的情况下接收返回到C#函数的Python列表并循环访问其元素:
using Python.Runtime;
internal sealed class Program
{
private static void Main(string[] args)
{
// NOTE: Set this based on your Python install.
// This will resolve from your PATH environment variable as well.
Runtime.PythonDLL = "python310.dll";
PythonEngine.Initialize();
using (Py.GIL())
{
using var scope = Py.CreateScope();
scope.Exec("number_list = [1, 2, 3, 4, 5]");
var pythonListObj = scope.Eval("number_list");
var csharpListObj = pythonListObj.As();
Console.WriteLine("The numbers from python are:");
foreach (var value in csharpListObj)
{
Console.WriteLine(value);
}
Console.WriteLine("Press enter to exit.");
Console.ReadLine();
}
}
}
在此示例中,我们使用 Exec方法创建一个Python列表,并将其分配给名为number_list。然后我们使用 Eval方法来获取对list对象的引用,然后,可以用整型数组(表示为int[])调用As
打印到控制台的数字在Python中声明,并从Pythonnet传递回C#。
总之,在C# .NET Core应用程序中使用Python是简单而无缝的。Python for .NET 提供了许多与Python解释器交互和调用Python函数的方法。通过使用这些方法,可以利用Python的强大功能在C# .NET Core应用程序中添加新功能。
本文最初发表于 https://www.devleader.ca/2023/01/20/pythonnet-a-simple-union-of-net-core-and-python-you'll-love
https://www.codeproject.com/Articles/5352648/Pythonnet-A-Simple-Union-of-NET-Core-and-Python-Yo