C# .Net通过pythonnet调用python pyd文件

开发环境:windows, python310, dotnet 6.0

说明:python文件编译成pyd。

1.新建控制台应用程序

2.添加nuget包

C# .Net通过pythonnet调用python pyd文件_第1张图片

3.C#调用代码

using Python.Runtime;

Runtime.PythonDLL= @"D:\Programs\Python\Python310\python310.dll";
PythonEngine.Initialize();
using (Py.GIL())
{
    dynamic np = Py.Import("PythonTest");
    var dd = np.cal("aa");
    Console.ReadLine();
}

C# .Net通过pythonnet调用python pyd文件_第2张图片

 调试可以看到python脚本返回的代码。

注意:请将PythonDLL路径改为自己的python安装路径;PythonTest为编译好的pyd文件,请将该文件复制到控制台程序debug目录,或者复制到控制台程序里面,将其属性复制到输出目录改为始终复制。

4.附录python脚本

def cal(param):
    return f'this is from python program, and the parameter is {param}'

******************************************2022-10-13 更新*************************************************

对于简单的py文件上面的方法可以很容易执行,但是对于引用外部package,比如pandas, numpy等等,我们调用的时候会抛出异常 “未找到相应的模块”。仔细一想就会知道,我们只打包了单个py文件,它所依赖的package当然会找不到。下面就是来解决这个问题。

我所测试的环境python版本变成了python 3.8.10。

我们只需要将下面代码放在using(Py.GIL())之前就可以:

string pathToVirtualEnv = @"D:\Programs\Python\Python3.8.10";
Environment.SetEnvironmentVariable("PATH", pathToVirtualEnv, EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("PYTHONHOME", pathToVirtualEnv, EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("PYTHONPATH", $"{pathToVirtualEnv}\\Lib\\site-packages;{pathToVirtualEnv}\\Lib", EnvironmentVariableTarget.Process);

Runtime.PythonDLL= @"D:\Programs\Python\Python3.8.10\python38.dll";
PythonEngine.PythonHome = pathToVirtualEnv;
PythonEngine.PythonPath = PythonEngine.PythonPath + ";" + Environment.GetEnvironmentVariable("PYTHONPATH", EnvironmentVariableTarget.Process);
PythonEngine.Initialize();

在你执行的过程中如果抛出找不到对应包的异常,你需要在PyCharm里面执行pip install 。这个命令会将package安装在我们的python安装目录下的Lib\site-package下。

当然你也可以使用指定的路径,具体方法可以参考下面的链接:

Setting Virtual Environment while Embedding Python in C#

Using Python.NET with Virtual Environments

不管哪一种,最重要的是需要在代码里配置PYTHONPATH, 让我们的程序可以有地方去找package。

比如.net core项目,我复制了python安装包的DLLs, Lib文件夹和python38.dll文件到bin\\dubug\\net6.0\\python\python3.8。

只需要将上面代码的pathToVirtualEnv改成新的路径即可:

//string pathToVirtualEnv = @"D:\Programs\Python\Python3.8.10"
string pathToVirtualEnv = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location), "Python\\Python3.8");

转载请注明出处,谢谢!

你可能感兴趣的:(python,c#,.netcore)