如何不用安装python就能在.NET里调用Python库


Posted in Python onJuly 12, 2019

前言

Pythonnet这个?疟?南钅康某鱿郑?沟梦颐强梢杂靡恢中碌姆绞剑??#可以和Python之间进行互操作。但是它的设置和部署可能有点问题,真的是这样吗?

本文我会介绍Python.Included这个项目,它不但优雅的解决了这个问题,并且让.NET开发者可以轻松愉快的让.NET与Python进行互操作。作为概念的证明,我将使用Numpy.Net进行展示,它是一个.NET标准库,它为Python的Numpy提供了一个强类型API,并且使用它并不需要在Windows上安装Python。

如何不用安装python就能在.NET里调用Python库

开发人员从Numpy.NET的强类型API中获益,与动态API不同,后者支持Visual Studio的IntelliSense功能,可以显示原始的Numpy文档。

问题是什么?

每个人可能都安装了不同版本的Python,有一些人用Python 2.7,其他一些人用Python 3.5,3.6甚至3.7。当你使用pythonnet的时候,针对Python的每个小版本,它必须使用不同的配置进行编译,而且该版本的Python必须安装,这样代码才可以运行。所以如果你在团队里工作,每个人就必须配置完全相同的Python环境。但拿我们的SciSharp团队来说,情况就已经不是这样的了。如果你想部署你的.NET应用,你首先必须部署Python,从开发人员角度来讲,这很闹心。

然而,如果你正在搞机器学习和人工智能,尽管微软和SciSharp都付出了很大努力,但目前你还是无法完全避免Python的使用。如果你看一下正在使用pythonnet的项目的列表,你会发现很多AI领域的公司当前都在使用.NET与Python进行连接。

Python.Included 前来救援

如果你可以很简单的引用一个Nuget包,并在无需手动修改的情况下,一切都会自动的配置好,假如可以达到这种程度,你会感觉怎么样?这就是我创建Python.Included的愿景,Python.Included可以把packages python-3.7.3-embed-amd64.zip包含在它的程序集里,这这样就允许你可以通过Nuget来有效的引用Python了。为了证明它能正常工作,并可以快速提供所有的NumSharp中仍然缺少的Numpy功能,我创建了基于Python.Included的Numpy.NET这个项目。

概念验证:Numpy.NET

Numpy.NET为Numpy提供了强类型的包装函数,这意味着您完全不需要使用dynamic关键字,但这部分我会在另一篇文章中深入讨论。今天的重点是介绍 Numpy.NET 如何使用 Python.Included 来按需自动部署Python和Numpy以便对它们进行调用。

这是Numpy将在幕后实际执行的设置代码。这些都不需要你来操作。一旦你使用了它的一个函数:

var a = np.array(new [,] {{1, 2}, {3, 4}});,

Numpy.dll 就会设置好嵌入的Python发行版,而它是从你本机home目录里的程序集里解压缩出来的(如果还没安装过的话)。

var installer = new Python.Included.Installer();
installer.SetupPython(force:false).Wait();

下一步(如果在之前的运行中还没完成)它将解压缩 numpy pip wheel,而numpy pip wheel 是作为嵌入的资源打包到了Numpy.dll里的并其安装到了Python安装文件里。

installer.InstallWheel(typeof(NumPy).Assembly, "numpy-1.16.3-cp37-cp37m-win_amd64.whl").Wait();

最后,pythonnet运行时被初始化了,Numpy也被导入进来了,可供后续使用。

PythonEngine.Initialize();
Py.Import("numpy");

这些都是在幕后发生的,使用Numpy.dll的用户根本不用担心本地的Python安装。事实上,即使您已安装了任何版本的Python也无所谓。

性能注意事项

大家都知道pythonnet比较慢,因此您可能会问自己,使用pythonnet将Python库与.NET接在一起是否真的是一个好主意。一如既往,这要看情况而定。

我的测试结果表明,与直接从Python调用Numpy相比,使用.net调用numpy的开销大约是它的4倍。需要澄清一下,这并不意味着Numpy.NET比python中的numpy慢四倍,这仅仅意味着通过pythonnet调用Numpy会有额外的开销。当然了,由于Numpy.NET调用的是Numpy,Numpy函数本身的执行时间是完全相同的。

开销是否是一个问题完全取决于实际用例。如果您在一个嵌套循环中不断的在CLR和Python之间来回切换,那就可能会遇到问题。但大多数Python库的设计都都是为了提高效率,避免数据循环。Numpy允许您只使用一个调用就可以对数百万的数组元素进行操作。Pytorch和Tensorflow允许您完全在GPU上执行操作。因此,如果正确使用,与处理大量数据时操作的执行时间相比,互操作开销可以忽略不计。

路线图

我知道现在有很多把Numpy移植到.NET上的方案和项目,例如使用IronPython。但是IronPython项目仍然只支持Python 2.7,而且项目进展非常缓慢。这就导致了依赖于python 3的库不能通过IronPython来获得和使用,而且这种情况在近期也不会有什么改变。

我的重点是通过pythonnet为.NET提供更多的机器学习和人工智能库。SciSharp团队也在讨论如何研发出一个更快版本的pythonnet,从而避免使用天性缓慢的DynamicObject。

请尝试一下Numpy.NET,并让我知道它为你做了什么并且做的如何。如果有任何意见或建议,我将不胜感激,我希望我的工作能够帮助.NET机器学习社区成长和繁荣。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
详解Python迭代和迭代器
Mar 28 Python
Python 专题六 局部变量、全局变量global、导入模块变量
Mar 20 Python
Python实现二维数组按照某行或列排序的方法【numpy lexsort】
Sep 22 Python
详解python中的线程
Feb 10 Python
详解Python中如何写控制台进度条的整理
Mar 07 Python
使用sklearn进行对数据标准化、归一化以及将数据还原的方法
Jul 11 Python
Python定时发送消息的脚本:每天跟你女朋友说晚安
Oct 21 Python
Python中Numpy ndarray的使用详解
May 24 Python
pytorch:实现简单的GAN示例(MNIST数据集)
Jan 10 Python
python代码实现将列表中重复元素之间的内容全部滤除
May 22 Python
python递归函数用法详解
Oct 26 Python
Python基于opencv的简单图像轮廓形状识别(全网最简单最少代码)
Jan 28 Python
python 执行终端/控制台命令的例子
Jul 12 #Python
python IDLE 背景以及字体大小的修改方法
Jul 12 #Python
Python-Tkinter Text输入内容在界面显示的实例
Jul 12 #Python
Python爬虫抓取技术的一些经验
Jul 12 #Python
python 使用装饰器并记录log的示例代码
Jul 12 #Python
如何使用python爬虫爬取要登陆的网站
Jul 12 #Python
Pycharm使用之设置代码字体大小和颜色主题的教程
Jul 12 #Python
You might like
php目录操作函数之获取目录与文件的类型
2010/12/29 PHP
PHP curl 获取响应的状态码的方法
2014/01/13 PHP
php数组合并的二种方法
2014/03/21 PHP
ThinkPHP2.0读取MSSQL提示Incorrect syntax near the keyword 'AS'的解决方法
2014/06/25 PHP
Javascript remove 自定义数组删除方法
2009/10/20 Javascript
用Juery网页选项卡实现代码
2011/06/13 Javascript
jquery实现背景墙聚光灯效果示例分享
2014/03/02 Javascript
jquery使用on绑定a标签无效 只能用live解决
2016/06/02 Javascript
第十篇BootStrap轮播插件使用详解
2016/06/21 Javascript
JavaScript分步实现一个出生日期的正则表达式
2018/03/22 Javascript
详解基于Koa2开发微信二维码扫码支付相关流程
2018/05/16 Javascript
解决vue动态为数据添加新属性遇到的问题
2018/09/18 Javascript
react同构实践之实现自己的同构模板
2019/03/13 Javascript
js实现web调用摄像头 js截取视频画面
2019/04/21 Javascript
小程序如何使用分包加载的实现方法
2019/05/22 Javascript
详解将微信小程序接口Promise化并使用async函数
2019/08/05 Javascript
Vue 实现html中根据类型显示内容
2019/10/28 Javascript
微信小程序 this.triggerEvent()的具体使用
2019/12/10 Javascript
在vue中实现清除echarts上次保留的数据(亲测有效)
2020/09/09 Javascript
python django 访问静态文件出现404或500错误
2017/01/20 Python
答题辅助python代码实现
2018/01/16 Python
Python多线程扫描端口代码示例
2018/02/09 Python
Python操作Mongodb数据库的方法小结
2019/09/10 Python
Python函数式编程指南:对生成器全面讲解
2019/11/19 Python
python读取raw binary图片并提取统计信息的实例
2020/01/09 Python
关于keras中keras.layers.merge的用法说明
2020/05/23 Python
Selenium及python实现滚动操作多种方法
2020/07/21 Python
CSS3实现水平居中、垂直居中、水平垂直居中的实例代码
2020/02/27 HTML / CSS
详解利用css3的var()实现运行时改变scss的变量值
2021/03/02 HTML / CSS
美国网上鞋城:Shoeline.com
2016/11/17 全球购物
美国眼镜网站:LensCrafters
2020/01/19 全球购物
医生实习工作总结的自我评价
2013/09/27 职场文书
网络工程专业毕业生推荐信
2013/10/28 职场文书
2014优秀党员事迹材料
2014/08/14 职场文书
不服从公司安排检讨书
2014/09/24 职场文书
MyBatis在注解上使用动态SQL方式(@select使用if)
2022/07/07 Java/Android