C#使用Python.NET执行Python脚本文件踩坑总结

news/2024/12/27 2:19:03/文章来源:https://www.cnblogs.com/gnix-a/p/18631116
  • 在VS,Nuget包管理器搜索“Python.NET”,安装pythonnet包,如下图:
  • C#使用Python.NET执行Python脚本文件,C#代码如下:
     1 public class PythonExecuter
     2 {
     3     private readonly string _pythonDllPath;
     4     private readonly string _workDir;
     5 
     6     public PythonExecuter(string dllPath, string workDir)
     7     {
     8         _pythonDllPath = dllPath;
     9         _workDir = workDir;
    10     }
    11 
    12     public async Task<bool> ExecutePythonScript(string scriptName)
    13     {
    14         bool result = false;
    15         Runtime.PythonDLL = _pythonDllPath;
    16         PythonEngine.Initialize();
    17         dynamic sys = Py.Import("sys");
    18         sys.path.append(_workDir);
    19         PythonEngine.BeginAllowThreads();
    20         await Task.Run(() =>
    21         {
    22             try
    23             {
    24                 using (Py.GIL())
    25                 {
    26                     Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} python脚本准备执行");
    27                     dynamic testModule = Py.Import(scriptName);// 导入模块(传入py文件名即可)
    28                     dynamic py = testModule.main();// 执行该py脚本的main函数
    29                     Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} 执行python脚本成功,返回值:{py}");
    30                     result = (int)py == 0;
    31                 }
    32             }
    33             catch (Exception ex)
    34             {
    35                 Console.WriteLine(ex.ToString());
    36             }
    37         });
    38 
    39         AppContext.SetSwitch("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", true);
    40         PythonEngine.Shutdown();
    41         AppContext.SetSwitch("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", false);
    42 
    43         return result;
    44     }
    45 }
  • 我的Python代码如下(有一个main函数,main函数调用了test函数):
  • 调用和执行结果如下:
  • 1 PythonExecuter executer = new(@"D:\Python\python313.dll", @"C:\Users\megarobo\PycharmProjects\pythonProject");
    2 bool result = await executer.ExecutePythonScript("pylabrobot");
    3 Console.ReadKey();
  • 执行结果包括Python脚本执行的打印输出内容。
  • 踩坑点说明
  1. 确保在代码中设置了Runtime.PythonDLL属性,指向正确的Python DLL文件。例如,如果你的Python版本是3.8,那么DLL文件名通常是python38.dll(Windows,Python安装根目录下);
  2. 设置工作目录,如果你的Python脚本.py文件在指定“_workDir”目录下(这样你的.py文件才能作为模块被导入),需要调用如下代码:
    1 dynamic sys = Py.Import("sys");
    2 sys.path.append(_workDir);
  3. using (Py.GIL())代码块的作用:在 Python.NET中,Py.GIL() 用于确保在当前线程中执行Python代码时,GIL被持有,这样可以安全地调用Python代码而不会破坏Python对象的状态。using语句确保在代码块执行完毕后,GIL会被正确释放;
  4. 如果你想在C#多线程中,使用Python对象(如上图我在Task.Run()中运行),需要调用PythonEngine.BeginAllowThreads(),否则无法达到预期效果;
  5. PythonEngine初始化后,执行完Python脚本后,需要释放资源。但直接调用PythonEngine.Shutdown()报错:BinaryFormatter serialization and deserialization are disabled within this application。这是因为 .NET 5 及更高版本出于安全考虑默认禁用了 BinaryFormatterPython.NET 在执行 PythonEngine.Shutdown() 时依赖于 BinaryFormatter。所以我们可以使用 AppContext 设置开关来临时启用 BinaryFormatter。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/858788.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PoerPC平台下的ethtool工具的编译

1. 编译器安装 2. 编译过程 参考:ethtool工具源码交叉编译_ethtool交叉编译-CSDN博客 注:步骤3中的config配置中,通过sudo apt-get install pkg-config libmnl-dev修复完问题后,需要重新执行一次步骤2中的./autogen.sh下载目标程序

微信小程序开发总结

业务需要,最近又搞起了微信小程序,之前从来没有参与过小程序的开发,对于开发中的流程也是知之甚少,正好学习一下,开搞... 前提:使用企业注册小程序 微信认证 小程序备案 [本地开发] 1.获取appid和secret 管理 > 开发管理 获取即可, 需要管理员扫码确认这里获取到的appid在使…

windows 下面使用 celery 管理定时任务

Python 实现定时任务有以下几种思路使用子进程(现成)+ time.sleep 间隔执行 使用现有的库管理定时任务如,celery, tornado等 使用系统的机制执行linux 下面 crontab ,windows 下面taskschd.msc本次调查 celery 这个常用的异步任务管理框架,它有一下好处支持分布式 支持任…

Goby 漏洞发布|CVE-2024-9047 WordPress File Upload 插件 wfu_file_downloader.php 任意文件读取漏洞

漏洞名称:CVE-2024-9047 WordPress File Upload 插件 wfu_file_downloader.php 任意文件读取漏洞 English Name:CVE-2024-9047 WordPress File Upload Plugin wfu_file_downloader.php Arbitrary File Read Vulnerabilit CVSS core: 6.8 漏洞描述: WordPress File Upload插件…

002. 队列安排(洛谷P1160)

002. 队列安排(洛谷P1160) 题目描述 一个学校里老师要将班上 \(N\) 个同学排成一列,同学被编号为 \(1\sim N\),他采取如下的方法:先将 \(1\) 号同学安排进队列,这时队列中只有他一个人;\(2\sim N\) 号同学依次入列,编号为 \(i\) 的同学入列方式为:老师指定编号为 \(i\) …

一个GLSL Shader的格式化算法(LALR解析器)

一个GLSL Shader的格式化算法(LALR解析器) 在进行OpenGL程序开发时,我需要自行解析`string`类型的Shader代码,抽取出里面的某些变量名和subroutine名。 由于找不到可用的GLSL Shader解析器,就照着虎书(《现代编译原理-c语言描述》)自己写了个LALR Generator,实际上包含了…

adb使用教程

谷歌官方出品用来控制安卓手机的工具1、作用打印日志定位bug稳定性测试运行设备的shell命令上传和下载文件安装和卸载设备上的应用等2、adb的安装配置Android开发官网下载ADB压缩包解压压缩包将ADB包放到根目录下将ADB路径加入到环境变量里3、用adb连接手机 进入开发者模式USB连…

中考阅读理解深入逻辑分析-005 A Tale of Bears and Belonging 熊的故事与归属感

文章正文 Dear Mr. Henshaw, ​ I finished Beggar Bears in two nights. It is a really good book. At first, I was surprised because it wasn’t funny like your other books, but then I got to thinking (you said readers should think) and decided a book …

PCIe扫盲——BDF与配置空间

前面的文章中介绍过,每一个PCIe设备可以只有一个功能(Function),即Fun0。也可以拥有最多8个功能,即多功能设备(Multi-Fun)。不管这个PCIe设备拥有多少个功能,其每一个功能都有一个唯一独立的配置空间(Configuration Space)与之对应。 和PCI总线一样,PCIe总线中的每一…

路由器透明代理

​1、下载OpenWrt 找各自路由型号----下载地址:https://firmware-selector.openwrt.org/​ 下载完后我们通过以下步骤让路由器进入刷机模式并准备好刷机:关闭路由器电源 按住复位键并接入电源,此时你会看到电源LED灯变成橙色等闪烁,接着会变为白色灯闪烁,此时可以放开复位…

SpringBoot 集成RabbitMQ

springboot集成MQ 配置文件配置类 发送者 消费者 调用