文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

怎么使用C#/.net程序调用Python

2023-07-05 08:16

关注

这篇文章主要介绍了怎么使用C#/.net程序调用Python的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么使用C#/.net程序调用Python文章都会有所收获,下面我们一起来看看吧。

C#/.net程序调用python

C#的优势在于window下的开发,不仅功能强大而且开发周期短。而python则有众多的第三方库,可以避免自己造轮子,利用C#来做界面,而具体实现使用python来实现可以大大提高开发效率。本文介绍如何使用pythonnet来执行python脚本,使用pythonnet既可以具有较高的交互性,又可以使用第三方python库,同时可以将程序需要的python环境及第三方库打包到软件中,避免用户进行python的环境配置。

C#调用python的常见方法

调用python常见的方法有4种

方式优点缺点
使用IronPython无需安装python运行环境,交互性强,C#和python无缝连接某些python第三方库不支持,如numpy
使用C++调用Python,然后将C++程序做成动态链接库交互性较强需要用户配置Python环境,实现方式复杂
利用C#命令行调用py文件执行速度快需要用户配置Python环境,交互性差
将python文件打包成exe进行调用无需安装python运行环境,执行速度慢,传递数据复杂,交互性差

可以看出4种方式均有限制,很难同时满足:交互性强、可调用第三方python库、无需用户配置Python环境要求,而这几项要求恰恰是一款成熟软件所必须的。而使用pythonnet库可满足以上三点要求。

本文均在.net 6环境下测试

使用pythonnet

string pathToVirtualEnv = ".\\envs\\pythonnetTest";Runtime.PythonDLL = Path.Combine(pathToVirtualEnv, "python39.dll");PythonEngine.PythonHome = Path.Combine(pathToVirtualEnv, "python.exe");PythonEngine.PythonPath = $"{pathToVirtualEnv}\\Lib\\site-packages;{pathToVirtualEnv}\\Lib";PythonEngine.Initialize();//调用无参无返回值方法using (Py.GIL()) //执行python的调用应该放在using (Py.GIL())块内{    //python对象应声明为dynamic类型    dynamic np = Py.Import("test");    np.hello();}//调用有参有返回值方法using (Py.GIL()){    dynamic np = Py.Import("test");    int r = np.add(1, 2);    Console.WriteLine($"计算结果{r}");}

python文件,必须放在PythonEngine.PythonPath设定的目录下

def hello():    print("hello")def add(a,b):    return a+b

嵌入Python环境及使用第三方库

程序中包含Python脚本所需要的所有环境以及第三方库可以免去用户的自定义配置。本文使用Anaconda来构建专用的虚拟环境。

string pathToVirtualEnv = ".\\envs\\pythonnetTest";Runtime.PythonDLL = Path.Combine(pathToVirtualEnv, "python39.dll");PythonEngine.PythonHome = Path.Combine(pathToVirtualEnv, "python.exe");PythonEngine.PythonPath = $"{pathToVirtualEnv}\\Lib\\site-packages;{pathToVirtualEnv}\\Lib";PythonEngine.Initialize()//使用第三方库using (Py.GIL()){    dynamic np = Py.Import("numpy");    Console.WriteLine(np.cos(np.pi * 2));    dynamic sin = np.sin;    Console.WriteLine(sin(5));    double c = (double)(np.cos(5) + sin(5));    Console.WriteLine(c);    dynamic a = np.array(new List<float> { 1, 2, 3 });    Console.WriteLine(a.dtype);    dynamic b = np.array(new List<float> { 6, 5, 4 }, dtype: np.int32);    Console.WriteLine(b.dtype);    Console.WriteLine(a * b);    Console.ReadKey();}

怎么使用C#/.net程序调用Python

注意:C#和python对象进行数学运算时,必须将Python对象放到前面,例如np.pi*2,不能是2*np.pi

传递对象

可以将C#对象传递到python中

在C#中定义对象

public class Person{    public Person(string firstName, string lastName)    {        FirstName = firstName;        LastName = lastName;    }    public string FirstName { get; set; }    public string LastName { get; set; }}
string pathToVirtualEnv = ".\\envs\\pythonnetTest";Runtime.PythonDLL = Path.Combine(pathToVirtualEnv, "python39.dll");PythonEngine.PythonHome = Path.Combine(pathToVirtualEnv, "python.exe");PythonEngine.PythonPath = $"{pathToVirtualEnv}\\Lib\\site-packages;{pathToVirtualEnv}\\Lib";PythonEngine.Initialize();//将C#中定义的类型传入pythonusing (Py.GIL()) {    Person p = new Person("John", "Smith");PyObject pyPerson = p.ToPython();string r1 = test.FullName(pyPerson);Console.WriteLine($"全名:{r1}");}

python脚本

def FullName(p):    return p.FirstName+""+p.LastName

怎么使用C#/.net程序调用Python

调用pyd文件

pyd文件主要有以下2点作用:

将.py文件编译成pyd文件步骤如下:

pip install cython

在.py文件目录下创建setup.py文件

from distutils.core import setupfrom Cython.Build import cythonizesetup(name = "testName",ext_modules = cythonize("test.py"), #将test.py文件编译成pyd)

执行编译命令

python setup.py build_ext --inplace

最后生成的pyd文件一般是test+cpython版本-平台为文件名,可以重命名为test名称,也可以不管,使用时仍然可以按test调用。

调动pyd文件和调用py文件相同,但是执行效率大大增强,下文会对执行速度进行对比。

执行速度对比

在test.py中定义一个耗时函数

import timedef Count():    start = time.perf_counter()    sum = 0    for i in range(10000):        for j in range(10000):            sum = sum + i + j    print("sum = ", sum)    end = time.perf_counter()    runTime = end - start    runTime_ms = runTime * 1000    print("运行时间:", runTime, "秒")

直接执行test.py脚本

运行结果如下:

怎么使用C#/.net程序调用Python

在C#中调用Conut()函数

//运行时间测试Console.WriteLine("C#开始计时");Stopwatch stopWatch = new Stopwatch();stopWatch.Start();test.Count();stopWatch.Stop();Console.WriteLine($"C#计时结束{stopWatch.ElapsedMilliseconds}");

执行结果如下:

怎么使用C#/.net程序调用Python

可以看到,使用pythonnet调用python脚本会有一定的性能损失,不过在对性能要求不是十分高的条件下是可以接受的。

执行test.pyd文件

运行结果如下:

怎么使用C#/.net程序调用Python

从结果可以看出调用pyd比原生的py文件执行还要快,所以可以使用pythonnet来执行pyd文件,即实现代码保护又提升了执行效率。

关于“怎么使用C#/.net程序调用Python”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“怎么使用C#/.net程序调用Python”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯