聊聊c#与Python以及IronPython
简单说说这个意义。做了很久的c#,突然发现Python火了。就看看,估计这篇博文有点长,有点长,尽量包括主要的东西,还有点杂,浏览吧,选择自己喜欢的看看。
先看比较。网上一堆各种比较。但是主要比较语法。我感觉这个没有说的。Python语法就是简单,它的设计目的就是为了简洁。这个不管怎么比较都是Python简单。但是写了很久的c#,这样反而不习惯,因为c#有很多语法糖。其实c#最近都没有什么更新,后面再说这个。
再看性能,这个都说静态语言占据优势,具体我没有自己测试过。就不多说,大家有兴趣自己测试吧。
那么就是比起c#,java这些语言,Python的优势就是简洁小巧。先说到这里,后面再说。
接下来我们看看c#与Python的结合体IronPython。IronPython其实就是c#版本的Python的解释器,另外也有java版本的.这个玩意是微软支持的,但是作者是Python的原作者。
再来具体看看这个玩意的使用。可以在官网下载http://ironpython.net。也可以提供nuget直接加入。但是提醒大家的是这个玩意支持的Python3还不稳定,有的功能没有。
具体看看使用
1.代码中执行语句或者表达式
其实就是类似我们在Pyhon的交互下的输入。
ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
string script = "print('Hello world!')";
var sourceCode = engine.CreateScriptSourceFromString(script);
var result = sourceCode.Execute<object>(scope);
Console.WriteLine(result);
看例子,主要就是调用的方法
engine.CreateScriptSourceFromString
实现语句或者表达式的执行。
再来,看看语句的参数传入
ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
string script = "print('Hello %d' %number)";
scope.SetVariable("number", 123);
ScriptSource sourceCode = engine.CreateScriptSourceFromString(script);
var result = sourceCode.Execute<object>(scope);
Console.WriteLine(result);
看见没有,其实就是ScriptScope 这个东东,这个就是这一次的执行玩意,通过它传入参数的值。
因为这玩意是c#的解释器,所以有更加高级一点的东西支持。
定义一个c#类。
public class Foo
{
public string Name { get; set; }
public DateTime Birthday { get; set; }
public string DoSth()
{
return DateTime.Now.ToString();
}
}
再来一个例子
ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
string script = @"print('Hello %s' %foo.Name)
foo.DoSth()";//注意这里换行是必须的
Foo foo = new Foo()
{
Name = "阿萨德",
Birthday = new DateTime(1999,2,2)
};
scope.SetVariable("foo", foo);
ScriptSource sourceCode = engine.CreateScriptSourceFromString(script);
var result = sourceCode.Execute<object>(scope);
Console.WriteLine(result);
你会发现执行是成功的。抛开Python。.NET平台本来就是支持动态语言执行的,这就是dynamic关键字为什么可以有,不清楚你可以再回过头看看dynamic。其实又回到.Net平台执行了。
这里表达式执行就说完了。
2.执行py文件
这个就是一般的Python的样子了,继续看例子。
ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
string path = @"test.py";
Foo foo = new Foo()
{
Name = "阿萨德",
Birthday = new DateTime(1999,2,2)
};
scope.SetVariable("foo", foo);
ScriptSource sourceCode = engine.CreateScriptSourceFromFile(path);
var result = sourceCode.Execute<object>(scope);
Console.WriteLine(result);
把Doth方法移动到py文件,里面写入上面例子的表达式,可以看效果。
这样就介绍完了c#调用Python脚本了。
3.IronPython特性的混合编程
(1)函数调用
继续,例子走前面
ScriptRuntime pyRuntime = Python.CreateRuntime(); //创建一下运行环境
dynamic obj= pyRuntime.UseFile("debug.py");
int num1=3, num2=4;
int sum = obj.add(num1, num2); //调用Python文件中的求和函数
注意,上面的使用方法是c#直接调用py文件的add函数,这也是一种py文件的执行,但是它的使用已经和c#混在了一起。
(2)引入.NET库和对象
先看例子
from System import DateTime, String
formatStr = String.Format("{0} {1}", "Hello World! The current date and time is ", DateTime.Now)
print formatStr
print dir(String)
raw_input("press Enter to exit!")
这是一段Python代码,里面有使用.NET中的String和DateTime。这段代码可以使用前面的表达式方法或者py文件执行。这就直接使用了c#的东西。
再接着来一个,看例子
namespace CalcLib
{
public class Calc
{
public int Add(int a, int b)
{
return a + b;
}
public int Sub(int a, int b)
{
return a - b;
}
}
}
假如上面这个是开发的一个c#的CalcLib.dll,我现在需要按照Python来执行。
import clr
clr.AddReference('CalcLib')
#clr.AddReferenceToFile('CalcLib.dll')
from CalcLib import Calc
print dir(Calc)
calcObj = Calc()
print "result of 3+4 is:", calcObj.Add(3,4)
print "result of 10+2 is:", calcObj.Sub(10,2)
raw_input("press Enter to exit!")
这又是一段Python的代码了,就可以使用了。注意,这要求IronPython能够找到CalcLib.dll。把CalcLib.dll拷贝到项目的debug目录或者在在使用的IronPython时,添加路径,通过engine.SetSearchPaths设置。
好了,c#与Python的交互就聊到这里,更加复杂的就不说了。
3.接下来说说IronPython调用问题了
先贴段代码
//ScriptRuntime pyRuntime = Python.CreateRuntime(); //创建一下运行环境
//ScriptEngine engine = Python.CreateEngine();
//engine.CreateScriptSourceFromString("print('hello!')").Execute();
//Console.ReadLine();
ScriptRuntime pyRuntime = Python.CreateRuntime(); //创建一下运行环境
ScriptEngine engine = Python.CreateEngine();
engine.SetSearchPaths(new string[] { });//设置库的搜索
//ScriptScope obj = pyRuntime.UseFile("debug.py"); //调用一个Python文件
//obj.ImportModule("");
//engine.ImportModule("");
//pyRuntime.ExecuteFile("debug.py");
//ScriptScope runScope = pyRuntime.CreateScope();
ScriptScope engScope = engine.CreateScope();
dynamic obj= engine.ExecuteFile("debug.py",engScope);//开始调用解析(与Python文件调试过程一样)
obj= engine.CreateScriptSourceFromFile("debug.py", Encoding.UTF8);
int num1=3, num2=4;
int sum = obj.add(num1, num2); //调用Python文件中的求和函数
//Console.Write("Sum:");
看见没有,那一堆的调用方法,其实实现是一样的,这就是Python的设计思想和c#的不同。Python是一个方法解决一件事情,即使它不是那么优雅,也不会扩展成多个方法,而c#则是提供多个方法解决一件事情,看起来灵活,满足各种参数传递。
其实这里的真实的顺序ScriptRuntime,ScriptEngine,ScriptScope,ScriptSource。具体是什么大家自己搜索。
我们调用时,无非是IronPython自动在后面默认创建了。比如直接用ScriptEngine执行py文件,则ScriptRuntime默认创建了,反过来用ScriptRuntime执行,也是默认创建了一个ScriptEngine,还是调用了ScriptEngine。按照c#一般的使用方式所以给了下面的代码。
ScriptEngine engine = Python.CreateEngine();
//添加搜索路径
var path=engine.GetSearchPaths();
List<string> lst = new List<string>(path.Count);
lst.AddRange(path);
lst.Add("debug");
engine.SetSearchPaths(lst.ToArray());
//
engine.ImportModule("");//标准模板
engine.ExecuteFile("debug.py");
engine.Execute("print('hell0')");
// ScriptSource scriptSource=
//engine.CreateScriptSourceFromFile("debug.py");//这里有一个编译过程
// scriptSource.Execute();
//如果有方法调用。
dynamic rpython = engine.ExecuteFile("debug.py");
rpython.Add(3, 4);
这大概就是大家常见的过程了。另外我注释的部分编译过程,在引擎调用ExecuteFile方法时内部就默认创建调用了该过程。前面已经介绍了几个类的执行过程。
4.解决问题了
模块搜索
(1)
ScriptEngine engine = Python.CreateEngine();
engine.ImportModule("");//标准模板
(2)
//添加搜索路径
var path=engine.GetSearchPaths();
List<string> lst = new List<string>(path.Count);
lst.AddRange(path);
lst.Add("debug");
engine.SetSearchPaths(lst.ToArray());
(3)
var options = new Dictionary<string, object>();
options["Frames"] = true;
options["FullFrames"] = true;
ScriptEngine engine = Python.CreateEngine(options);
最好的解决方法,项目定住库的位置,然后在调用的py文件里面加入以下代码:
import re,sys
sys.path.append("C:\Users\Administrator\Desktop\python\ironPython\WebApplication1\Lib") //这是本地调式用库
sys.path.append("C:\ironPython\Lib")
直接把Python的问题放在Python中解决。
编辑器问题
编辑器所在主线程模式只能使用STA线程,这也是vs默认的。
这也就差不多了,最后说说vs2017开发.
在vs2017中可以开发Python.需要在vs安装选择Python.这样其实配置vs2017的一些环境(可以选择安装Python3.6,这是vs2017集成安装的版本)。会在项目创建中添加Python项。
另外值得注意的是,一些博文说VS安装的Python是建立在vs安装目录下,但是我当前机器已经安装了官网Python环境,所以vs创建Python默认环境就是我已经安装好的官网Python环境,但是发现可以右键Python环境进行修改添加。vs2017可以执行,但是没有编辑提示,需要安装插件python for visual studio。
值得一说的vs2017的Python项目创建里面是2类,一类是Python应用程序,一类是IronPython应用程序,看清楚了。都是需要环境的。
好了,回到正题了,说说c#与Python了。
一直以来形成了java占据web,c#占据桌面系统开发。这是和各自的生态环境相关的,由于.NET长期闭源,被java抢占了市场,java有很多开源组件。Python由于自己的特点,占据了数据分析,人工智能方面。所以是根据各自优势来的。
所以完整的比较是没有意义的。另外由于.NET这种大平台(还有java)是由有关企业占用主导,所以只会关注最基础的实现和提供库,不像Python是由社区来引导支持的,这就造成了一种局面。Python在某一方有开源的库支持,最后变成了标准,然后又以模块的方式提供。但是c#就不会,只会提供最基础的,然后专注技术优化,性能优化,新技术创新。这样就决定了市场环境。那么Python就多了一个优势,在某一方面有标准库(优秀的第三方库)来支持,而c#不会有,从定位和开发驱动就决定了。例如,c#就不可能专门提供数据分析类似Python的pandas,只会提供一般的数据处理类(例如文件读取,包括json处理都是第三方的),这就是c#的定位,否则会很臃肿。
接着说说c#,.NET,vs2017.简单说几句废话,c#是开发语言,是.NET平台支撑的一种。vs2017是开发工具,简单说就是编辑器,只是集成了.NET平台和各种库,这样vs2017就支撑了很多语言开发,c#,VB,java,js,vb,F#.所以vs2017变得臃肿巨大,.NET也在支撑,也在逐步增加,所以你看看,如果再提高某个方向的库,会变成什么样子。值得一说的是,其实到.NET4.0以后,基本就没有新的技术出现了,对于c#,只是提供了语法糖,编译器自动转换罢了,优势是我们自己的cs文件可能小了,编译器大了。
不多说,不然又是一堆废话,还不少。
对于一个大学生即将就业,哪个好?根据你所在的地方,能够让你就业就是好的。对于一个程序员,哪个好?哥们,别比较了,你已经有一门语言在吃饭了,对于你来说,这辈子很大可能不会只用一种语言开发。对于这么热门的数据分析和人工智能,你得学Python啊。其实语法很简单,你只需要了解库,到时网上查就是了。
最最后,前面虽然提到了混合编程,但是最好不要这么做。如果如例子那样调用c#库,既然是c#为啥不直接使用呢,还要多个Python方式,简直无语,不知道为啥会这样提供。所以一般情况是写好Python文件然后调用一个入口,返回结果就好了,混合编程完全没有必要,多次一举。
然后是注意Python库,官网Python实际是CPython.解释器是c写的,所以可以执行c代码库,但是IronPython是c#版本的,执行不了,而CPython为了速度,性能方面的优化,有些库是c的,所以打算混合开发前你要注意你的库了。还有就是前面说的IronPython现在支持2.7。3.x还不稳定,小心了。作为架构设计者,这些要注意了,最好不要混合编程,这种思路就是给自己挖坑,不到不得已的时候坚决不要有混合编程,需要填很多坑。
最后再为大家提供一个思路吧。把项目变成分布式服务。一端用c#,一端用CPython。用网络进行沟通。其实我们要用IronPython,就是因为Python有很多现成的库(某个方向,某个领域,例如前面提到的数据分析),一旦没有了,其实就没有必要了。作为设计者一定要平衡,或者用c#实现一个类似的库。这个投入就大了,就看老板的态度了,还要测试,最后还要和Python比较谁好,但愿随着c#开源,net core跨平台,有没有优秀的第三方库来支持,就
聊聊c#与Python以及IronPython的更多相关文章
- 最全总结 | 聊聊 Python 数据处理全家桶(PgSQL篇)
1. 前言 大家好,我是安果! Python 数据处理全家桶,截止到现在,一共写过 6 篇文章,有兴趣的小伙伴可以去了解一下! 最全总结 | 聊聊 Python 数据处理全家桶(Mysql 篇) 最全 ...
- python学习笔记1:python入门
关于版本的选择 按照网上的说法,如果python是为了在工作中使用,选择2.7版本的.这里我选择2.7.9版本的来进行学习: Python是什么? 是一种高级的计算机程序设计语言.应用范围比较广,go ...
- python学习笔记(python简史)
一.python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum) 目前python主要应用领域: ·云计算 ·WEB开发 ·科学运算.人工智能 ·系统运维 ·金融:量化交 ...
- 1 python大数据挖掘系列之基础知识入门
preface Python在大数据行业非常火爆近两年,as a pythonic,所以也得涉足下大数据分析,下面就聊聊它们. Python数据分析与挖掘技术概述 所谓数据分析,即对已知的数据进行分析 ...
- Python的平凡之路(1)
2016-07-26 一.Python简介 Python是一种解释型.面向对象.动态数据类型的高级程序设计语言.它的特点如下: 面向对象.解释语言.交互性.模块化.动态性.高级语言.可移植.可 ...
- 【转】使用Python的IDE:Eclipse+PyDev
原文网址:http://www.crifan.com/try_with_python_ide_eclipse_pydev/ 之前已经介绍过了一些基本知识: [整理][多图详解]如何在Windows下开 ...
- 人们对Python在企业级开发中的10大误解
From : 人们对Python在企业级开发中的10大误解 在PayPal的编程文化中存在着大量的语言多元化.除了长期流行的C++和Java,越来越多的团队选择JavaScript和Scala,Bra ...
- 从用python自动生成.h的头文件集合和类声明集合到用python读写文件
最近在用python自动生成c++的类.因为这些类会根据需求不同产生不同的类,所以需要用python自动生成.由于会产生大量的类,而且这些类是变化的.所以如果是在某个.h中要用include来加载这些 ...
- python编辑器对比和推荐
python编辑器对比和推荐 我先给一个初步的表格吧,大家如果有什么意见,或有补充,欢迎提出.有些我没有用过,先不写了.以下是我使用过的python IDE: 除了PythonWin, Visua ...
随机推荐
- 我的gulp第一个程序
以前都是单枪匹马的干,从没用过模块化的打包工具,加入新的团队后,模块化开发学到不少,尤其是工具的使用.团队目前较多的使用gulp,也是最流行的一款前端打包工具.最近Team开始尝试用gulp,我也只是 ...
- <Android 应用 之路> MPAndroidChart~BarChart
简介 MPAndroidChart是PhilJay大神给Android开发者带来的福利.MPAndroidChart是一个功能强大并且使用灵活的图表开源库,支持Android和IOS两种,这里我们暂时 ...
- Android TabHost切换选项卡实现数据实时刷新
手机界面大小有限,使用TabHost可以达到在一个Activity中放入多个容器(界面)的效果.但存在一个问题是,当数据信息在一个容器(界面)中有所改变时,需要在用户切换选项卡到其他容器(界面)的时候 ...
- html 标签 显示模式
1.html 标签模式分为三类:块级标签,行内标签(内联),行内块标签 a. 块级标签 典型代表:div.h1~h6.p.ul.ol.li.dl.dt.dd等. 特点:可以设置宽高,独占一行 b.行内 ...
- Anaconda 执行命令报ssl错误
- idea智能提示 不管用 问题
今天碰到个问题,idea的智能提示 死活不能使用了.同一个包下的类竟然还没有智能提示,无语了... 搜了好多篇文章,虽然知道 重装可以解决... 这样设置就可以了:
- git revert .vs. git reset .vs. git rebase
1. git rervert的工作方式是:将一个老的commit的改动完全找出来,并且在新的tip处运行反操作,最终清除老commit的改动: git revert的应用场景多在对public rep ...
- pt-heartbeat(percona toolkit)
pt-heartbeat是用来监控主从延迟的一款percona工具,现在我们大部分的MySQL架构还是基于主从复制,例如MHA,MMM,keepalived等解决方案.而主从环境的话,我们很关心的就是 ...
- Oracle使用超大SQL脚本文件恢复数据问题记录
在以前获取的Oracle数据库备份一般都是dmp文件,创建表空间和用户就直接使用imp或者impdp导入即可. 这一次遇到的情况比较特殊,对方提供数据时给我的是使用SQLPlus导出的SQL脚本文件, ...
- Win10安装msi程序报错2503和2502错误解决方案
刚升级了系统到win10,重新搭建开发环境,在安装scala的时候一直报2503.2502错误,如图 试了好几种办法都不好使,现在罗列依次用到的三种方法: 一.命令提示符(管理员)启动 "w ...