C#使用IronPython调用python代码的实现示例
作者:淀粉肠狂热粉
找不到os:已解决
os是python基础包,这个都找不到实在很离谱。解法是在paths中增加os的路径。
首先在anaconda prompt中找到位置:
Python 3.9.13 (main, Aug 25 2022, 23:51:50) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32 Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> sys.path ... >>> import os >>> os <module 'os' from 'D:\\ProgramData\\Anaconda3\\lib\\os.py'> >>>
所以修改C#中调用部分:
... var paths = engine.GetSearchPaths(); paths.Add("C:\\Users\\xxxx\\.nuget\\packages\\ironpython\\3.4.1\\lib"); paths.Add("D:\\ProgramData\\Anaconda3\\lib"); // 这一句 engine.SetSearchPaths(paths); ...
此时报错消失。
invalid syntax:版本问题,未解决
C#中完整报错:
引发的异常:“Microsoft.Scripting.SyntaxErrorException”(位于 Microsoft.Dynamic.dll 中) “Microsoft.Scripting.SyntaxErrorException”类型的未经处理的异常在 Microsoft.Dynamic.dll 中发生 invalid syntax
参考这里:
Invalid syntax · Issue #1501 · IronLanguages/ironpython3 · GitHub
https://github.com/IronLanguages/ironpython3/issues/1501
我这里的问题就是python的版本,本地是3.9但是IronPython装的是3.4。这个暂时没法解决,所以我还是放弃在python中执行了。
2021/8/27更新:c#执行python的exe文件
这个的主要问题是慢。我的项目只用到matplotlib和biopython,所以通过创建虚拟环境,装包,然后用pyinstaller打包的方式构建可执行文件。简单测了一下,文件读取然后绘制4w+点就花了10s多。。实在不能忍。所以c#调用exe还是放弃吧。
DateTime beforeDT = System.DateTime.Now; string pyexePath = @"C:\XXXXXX\dist\drawGraph.exe"; Process p = new Process(); p.StartInfo.FileName = pyexePath; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardInput = true; p.StartInfo.CreateNoWindow = true; // 我的一个参数 p.StartInfo.Arguments = @"C:\XXXX\XXX.txt"; p.Start(); string output = p.StandardOutput.ReadToEnd(); p.WaitForExit(); Console.WriteLine(output); DateTime afterDT = System.DateTime.Now; TimeSpan ts = afterDT.Subtract(beforeDT); Console.WriteLine("Time: {0}s", ts.TotalSeconds); p.Close();
C#调用python代码和库的几种方法
使用IronPython,直接调用python文件
IronPython调用第三方库需要装库、设路径,可能报bug使用c++调用python,做成dll,在c#中调用dll
需要用户安装python环境,慢c#命令行调用py文件
需要用户安装python环境c#命令行调用python的exe文件
慢
先说结论
IronPython是一个帮助c#引用python代码的插件/库。但是,由于我的python代码中用到matplotlib和biopython,而这两个包都需要numpy,可是IronPython完全不支持numpy,所以我最终放弃了这个做法。因此本文只贴最最最简单的例子。
环境
win10 + vs 2019 + netframework 4.7.2
实例
首先在工具-NuGet包管理器中搜索IronPython,安装。我装的版本是 2.7.11。
这里我第一次傻 了,因为IronPython 2.7.*就是python 2.7,IronPython 3.4才是python 3的。
然后在wpf项目里放一个mywindow.py文件,内容为:
# -*- coding: utf-8 -*- import sys def text(): return str(sys.path)
调用的地方这样写:
using IronPython.Hosting; using Microsoft.Scripting.Hosting; public partial class WavePainter : Window { public WavePainter() { InitializeComponent(); //Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory); string basePath = AppDomain.CurrentDomain.BaseDirectory; string pyFilePath = basePath + @"..\..\py\mywindow.py"; ScriptRuntime pyRuntime = Python.CreateRuntime(); // 这里开始到dynamic py...行前都不是必须的。是指定lib path位置的 var engine = pyRuntime.GetEngine("python"); var pyScope = engine.CreateScope(); var paths = engine.GetSearchPaths(); paths.Add(basePath + @"..\..\packages\IronPython.2.7.11\lib"); engine.SetSearchPaths(paths); // 执行py文件 dynamic py = pyRuntime.UseFile(pyFilePath); string a = py.text(); tb1.Text = a; } }
可以看到sys.path是真的加入内容了。
当前,只做简单运算、不引用其他包的py代码是可以跑起来的,但是如果引用诸如os这种基础包都会报错,提示模块不存在。那么,如果实在要用,应该装对应的Python环境,然后把对应路径加到sys.path中来,那就是能跑的。
但是前面也说了,numpy用不了,而我的客户都没有python环境,我也不能强迫他们装,所以只能采取别的方式了,下次再更新解决方案。
到此这篇关于C#使用IronPython调用python代码的实现示例的文章就介绍到这了,更多相关C# IronPython调用python内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!